Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
/// This file defines OpenMP AST classes for executable directives and
10
/// clauses.
11
///
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_CLANG_AST_STMTOPENMP_H
15
#define LLVM_CLANG_AST_STMTOPENMP_H
16
 
17
#include "clang/AST/ASTContext.h"
18
#include "clang/AST/Expr.h"
19
#include "clang/AST/OpenMPClause.h"
20
#include "clang/AST/Stmt.h"
21
#include "clang/AST/StmtCXX.h"
22
#include "clang/Basic/OpenMPKinds.h"
23
#include "clang/Basic/SourceLocation.h"
24
 
25
namespace clang {
26
 
27
//===----------------------------------------------------------------------===//
28
// AST classes for directives.
29
//===----------------------------------------------------------------------===//
30
 
31
/// Representation of an OpenMP canonical loop.
32
///
33
/// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape
34
/// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape
35
/// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form
36
/// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form
37
/// OpenMP 4.0, section 2.6 Canonical Loop Form
38
/// OpenMP 4.5, section 2.6 Canonical Loop Form
39
/// OpenMP 5.0, section 2.9.1 Canonical Loop Form
40
/// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form
41
///
42
/// An OpenMP canonical loop is a for-statement or range-based for-statement
43
/// with additional requirements that ensure that the number of iterations is
44
/// known before entering the loop and allow skipping to an arbitrary iteration.
45
/// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is
46
/// known to fulfill OpenMP's canonical loop requirements because of being
47
/// associated to an OMPLoopBasedDirective. That is, the general structure is:
48
///
49
///  OMPLoopBasedDirective
50
/// [`- CapturedStmt   ]
51
/// [   `- CapturedDecl]
52
///        ` OMPCanonicalLoop
53
///          `- ForStmt/CXXForRangeStmt
54
///             `- Stmt
55
///
56
/// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some
57
/// directives such as OMPParallelForDirective, but others do not need them
58
/// (such as OMPTileDirective). In  The OMPCanonicalLoop and
59
/// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the
60
/// directive. A OMPCanonicalLoop must not appear in the AST unless associated
61
/// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the
62
/// OMPCanonicalLoop may also be wrapped in a CompoundStmt:
63
///
64
/// [...]
65
///  ` OMPCanonicalLoop
66
///    `- ForStmt/CXXForRangeStmt
67
///       `- CompoundStmt
68
///          |- Leading in-between code (if any)
69
///          |- OMPCanonicalLoop
70
///          |  `- ForStmt/CXXForRangeStmt
71
///          |     `- ...
72
///          `- Trailing in-between code (if any)
73
///
74
/// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
75
/// to avoid confusion which loop belongs to the nesting.
76
///
77
/// There are three different kinds of iteration variables for different
78
/// purposes:
79
/// * Loop user variable: The user-accessible variable with different value for
80
///   each iteration.
81
/// * Loop iteration variable: The variable used to identify a loop iteration;
82
///   for range-based for-statement, this is the hidden iterator '__begin'. For
83
///   other loops, it is identical to the loop user variable. Must be a
84
///   random-access iterator, pointer or integer type.
85
/// * Logical iteration counter: Normalized loop counter starting at 0 and
86
///   incrementing by one at each iteration. Allows abstracting over the type
87
///   of the loop iteration variable and is always an unsigned integer type
88
///   appropriate to represent the range of the loop iteration variable. Its
89
///   value corresponds to the logical iteration number in the OpenMP
90
///   specification.
91
///
92
/// This AST node provides two captured statements:
93
/// * The distance function which computes the number of iterations.
94
/// * The loop user variable function that computes the loop user variable when
95
///   given a logical iteration number.
96
///
97
/// These captured statements provide the link between C/C++ semantics and the
98
/// logical iteration counters used by the OpenMPIRBuilder which is
99
/// language-agnostic and therefore does not know e.g. how to advance a
100
/// random-access iterator. The OpenMPIRBuilder will use this information to
101
/// apply simd, workshare-loop, distribute, taskloop and loop directives to the
102
/// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an
103
/// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an
104
/// OMPLoopDirective and skipped when searching for the associated syntactical
105
/// loop.
106
///
107
/// Example:
108
/// <code>
109
///   std::vector<std::string> Container{1,2,3};
110
///   for (std::string Str : Container)
111
///      Body(Str);
112
/// </code>
113
/// which is syntactic sugar for approximately:
114
/// <code>
115
///   auto &&__range = Container;
116
///   auto __begin = std::begin(__range);
117
///   auto __end = std::end(__range);
118
///   for (; __begin != __end; ++__begin) {
119
///     std::String Str = *__begin;
120
///     Body(Str);
121
///   }
122
/// </code>
123
/// In this example, the loop user variable is `Str`, the loop iteration
124
/// variable is `__begin` of type `std::vector<std::string>::iterator` and the
125
/// logical iteration number type is `size_t` (unsigned version of
126
/// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`).
127
/// Therefore, the distance function will be
128
/// <code>
129
///   [&](size_t &Result) { Result = __end - __begin; }
130
/// </code>
131
/// and the loop variable function is
132
/// <code>
133
///   [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
134
///     Result = __begin + Logical;
135
///   }
136
/// </code>
137
/// The variable `__begin`, aka the loop iteration variable, is captured by
138
/// value because it is modified in the loop body, but both functions require
139
/// the initial value. The OpenMP specification explicitly leaves unspecified
140
/// when the loop expressions are evaluated such that a capture by reference is
141
/// sufficient.
142
class OMPCanonicalLoop : public Stmt {
143
  friend class ASTStmtReader;
144
  friend class ASTStmtWriter;
145
 
146
  /// Children of this AST node.
147
  enum {
148
    LOOP_STMT,
149
    DISTANCE_FUNC,
150
    LOOPVAR_FUNC,
151
    LOOPVAR_REF,
152
    LastSubStmt = LOOPVAR_REF
153
  };
154
 
155
private:
156
  /// This AST node's children.
157
  Stmt *SubStmts[LastSubStmt + 1] = {};
158
 
159
  OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
160
 
161
public:
162
  /// Create a new OMPCanonicalLoop.
163
  static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt,
164
                                  CapturedStmt *DistanceFunc,
165
                                  CapturedStmt *LoopVarFunc,
166
                                  DeclRefExpr *LoopVarRef) {
167
    OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop();
168
    S->setLoopStmt(LoopStmt);
169
    S->setDistanceFunc(DistanceFunc);
170
    S->setLoopVarFunc(LoopVarFunc);
171
    S->setLoopVarRef(LoopVarRef);
172
    return S;
173
  }
174
 
175
  /// Create an empty OMPCanonicalLoop for deserialization.
176
  static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) {
177
    return new (Ctx) OMPCanonicalLoop();
178
  }
179
 
180
  static bool classof(const Stmt *S) {
181
    return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
182
  }
183
 
184
  SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); }
185
  SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); }
186
 
187
  /// Return this AST node's children.
188
  /// @{
189
  child_range children() {
190
    return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
191
  }
192
  const_child_range children() const {
193
    return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
194
  }
195
  /// @}
196
 
197
  /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
198
  /// @{
199
  Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; }
200
  const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; }
201
  void setLoopStmt(Stmt *S) {
202
    assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) &&
203
           "Canonical loop must be a for loop (range-based or otherwise)");
204
    SubStmts[LOOP_STMT] = S;
205
  }
206
  /// @}
207
 
208
  /// The function that computes the number of loop iterations. Can be evaluated
209
  /// before entering the loop but after the syntactical loop's init
210
  /// statement(s).
211
  ///
212
  /// Function signature: void(LogicalTy &Result)
213
  /// Any values necessary to compute the distance are captures of the closure.
214
  /// @{
215
  CapturedStmt *getDistanceFunc() {
216
    return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
217
  }
218
  const CapturedStmt *getDistanceFunc() const {
219
    return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
220
  }
221
  void setDistanceFunc(CapturedStmt *S) {
222
    assert(S && "Expected non-null captured statement");
223
    SubStmts[DISTANCE_FUNC] = S;
224
  }
225
  /// @}
226
 
227
  /// The function that computes the loop user variable from a logical iteration
228
  /// counter. Can be evaluated as first statement in the loop.
229
  ///
230
  /// Function signature: void(LoopVarTy &Result, LogicalTy Number)
231
  /// Any other values required to compute the loop user variable (such as start
232
  /// value, step size) are captured by the closure. In particular, the initial
233
  /// value of loop iteration variable is captured by value to be unaffected by
234
  /// previous iterations.
235
  /// @{
236
  CapturedStmt *getLoopVarFunc() {
237
    return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
238
  }
239
  const CapturedStmt *getLoopVarFunc() const {
240
    return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
241
  }
242
  void setLoopVarFunc(CapturedStmt *S) {
243
    assert(S && "Expected non-null captured statement");
244
    SubStmts[LOOPVAR_FUNC] = S;
245
  }
246
  /// @}
247
 
248
  /// Reference to the loop user variable as accessed in the loop body.
249
  /// @{
250
  DeclRefExpr *getLoopVarRef() {
251
    return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
252
  }
253
  const DeclRefExpr *getLoopVarRef() const {
254
    return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
255
  }
256
  void setLoopVarRef(DeclRefExpr *E) {
257
    assert(E && "Expected non-null loop variable");
258
    SubStmts[LOOPVAR_REF] = E;
259
  }
260
  /// @}
261
};
262
 
263
/// This is a basic class for representing single OpenMP executable
264
/// directive.
265
///
266
class OMPExecutableDirective : public Stmt {
267
  friend class ASTStmtReader;
268
  friend class ASTStmtWriter;
269
 
270
  /// Kind of the directive.
271
  OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
272
  /// Starting location of the directive (directive keyword).
273
  SourceLocation StartLoc;
274
  /// Ending location of the directive.
275
  SourceLocation EndLoc;
276
 
277
  /// Get the clauses storage.
278
  MutableArrayRef<OMPClause *> getClauses() {
279
    if (!Data)
280
      return std::nullopt;
281
    return Data->getClauses();
282
  }
283
 
284
protected:
285
  /// Data, associated with the directive.
286
  OMPChildren *Data = nullptr;
287
 
288
  /// Build instance of directive of class \a K.
289
  ///
290
  /// \param SC Statement class.
291
  /// \param K Kind of OpenMP directive.
292
  /// \param StartLoc Starting location of the directive (directive keyword).
293
  /// \param EndLoc Ending location of the directive.
294
  ///
295
  OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K,
296
                         SourceLocation StartLoc, SourceLocation EndLoc)
297
      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
298
        EndLoc(std::move(EndLoc)) {}
299
 
300
  template <typename T, typename... Params>
301
  static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses,
302
                            Stmt *AssociatedStmt, unsigned NumChildren,
303
                            Params &&... P) {
304
    void *Mem =
305
        C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
306
                                                 NumChildren),
307
                   alignof(T));
308
 
309
    auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
310
                                     AssociatedStmt, NumChildren);
311
    auto *Inst = new (Mem) T(std::forward<Params>(P)...);
312
    Inst->Data = Data;
313
    return Inst;
314
  }
315
 
316
  template <typename T, typename... Params>
317
  static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
318
                                 bool HasAssociatedStmt, unsigned NumChildren,
319
                                 Params &&... P) {
320
    void *Mem =
321
        C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
322
                                                 NumChildren),
323
                   alignof(T));
324
    auto *Data =
325
        OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
326
                                 HasAssociatedStmt, NumChildren);
327
    auto *Inst = new (Mem) T(std::forward<Params>(P)...);
328
    Inst->Data = Data;
329
    return Inst;
330
  }
331
 
332
  template <typename T>
333
  static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
334
                                 bool HasAssociatedStmt = false,
335
                                 unsigned NumChildren = 0) {
336
    void *Mem =
337
        C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
338
                                                 NumChildren),
339
                   alignof(T));
340
    auto *Data =
341
        OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
342
                                 HasAssociatedStmt, NumChildren);
343
    auto *Inst = new (Mem) T;
344
    Inst->Data = Data;
345
    return Inst;
346
  }
347
 
348
public:
349
  /// Iterates over expressions/statements used in the construct.
350
  class used_clauses_child_iterator
351
      : public llvm::iterator_adaptor_base<
352
            used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
353
            std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
354
    ArrayRef<OMPClause *>::iterator End;
355
    OMPClause::child_iterator ChildI, ChildEnd;
356
 
357
    void MoveToNext() {
358
      if (ChildI != ChildEnd)
359
        return;
360
      while (this->I != End) {
361
        ++this->I;
362
        if (this->I != End) {
363
          ChildI = (*this->I)->used_children().begin();
364
          ChildEnd = (*this->I)->used_children().end();
365
          if (ChildI != ChildEnd)
366
            return;
367
        }
368
      }
369
    }
370
 
371
  public:
372
    explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
373
        : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
374
          End(Clauses.end()) {
375
      if (this->I != End) {
376
        ChildI = (*this->I)->used_children().begin();
377
        ChildEnd = (*this->I)->used_children().end();
378
        MoveToNext();
379
      }
380
    }
381
    Stmt *operator*() const { return *ChildI; }
382
    Stmt *operator->() const { return **this; }
383
 
384
    used_clauses_child_iterator &operator++() {
385
      ++ChildI;
386
      if (ChildI != ChildEnd)
387
        return *this;
388
      if (this->I != End) {
389
        ++this->I;
390
        if (this->I != End) {
391
          ChildI = (*this->I)->used_children().begin();
392
          ChildEnd = (*this->I)->used_children().end();
393
        }
394
      }
395
      MoveToNext();
396
      return *this;
397
    }
398
  };
399
 
400
  static llvm::iterator_range<used_clauses_child_iterator>
401
  used_clauses_children(ArrayRef<OMPClause *> Clauses) {
402
    return {
403
        used_clauses_child_iterator(Clauses),
404
        used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
405
  }
406
 
407
  /// Iterates over a filtered subrange of clauses applied to a
408
  /// directive.
409
  ///
410
  /// This iterator visits only clauses of type SpecificClause.
411
  template <typename SpecificClause>
412
  class specific_clause_iterator
413
      : public llvm::iterator_adaptor_base<
414
            specific_clause_iterator<SpecificClause>,
415
            ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
416
            const SpecificClause *, ptrdiff_t, const SpecificClause *,
417
            const SpecificClause *> {
418
    ArrayRef<OMPClause *>::const_iterator End;
419
 
420
    void SkipToNextClause() {
421
      while (this->I != End && !isa<SpecificClause>(*this->I))
422
        ++this->I;
423
    }
424
 
425
  public:
426
    explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
427
        : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
428
          End(Clauses.end()) {
429
      SkipToNextClause();
430
    }
431
 
432
    const SpecificClause *operator*() const {
433
      return cast<SpecificClause>(*this->I);
434
    }
435
    const SpecificClause *operator->() const { return **this; }
436
 
437
    specific_clause_iterator &operator++() {
438
      ++this->I;
439
      SkipToNextClause();
440
      return *this;
441
    }
442
  };
443
 
444
  template <typename SpecificClause>
445
  static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
446
  getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
447
    return {specific_clause_iterator<SpecificClause>(Clauses),
448
            specific_clause_iterator<SpecificClause>(
449
                llvm::ArrayRef(Clauses.end(), (size_t)0))};
450
  }
451
 
452
  template <typename SpecificClause>
453
  llvm::iterator_range<specific_clause_iterator<SpecificClause>>
454
  getClausesOfKind() const {
455
    return getClausesOfKind<SpecificClause>(clauses());
456
  }
457
 
458
  /// Gets a single clause of the specified kind associated with the
459
  /// current directive iff there is only one clause of this kind (and assertion
460
  /// is fired if there is more than one clause is associated with the
461
  /// directive). Returns nullptr if no clause of this kind is associated with
462
  /// the directive.
463
  template <typename SpecificClause>
464
  static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
465
    auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
466
 
467
    if (ClausesOfKind.begin() != ClausesOfKind.end()) {
468
      assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
469
             "There are at least 2 clauses of the specified kind");
470
      return *ClausesOfKind.begin();
471
    }
472
    return nullptr;
473
  }
474
 
475
  template <typename SpecificClause>
476
  const SpecificClause *getSingleClause() const {
477
    return getSingleClause<SpecificClause>(clauses());
478
  }
479
 
480
  /// Returns true if the current directive has one or more clauses of a
481
  /// specific kind.
482
  template <typename SpecificClause>
483
  bool hasClausesOfKind() const {
484
    auto Clauses = getClausesOfKind<SpecificClause>();
485
    return Clauses.begin() != Clauses.end();
486
  }
487
 
488
  /// Returns starting location of directive kind.
489
  SourceLocation getBeginLoc() const { return StartLoc; }
490
  /// Returns ending location of directive.
491
  SourceLocation getEndLoc() const { return EndLoc; }
492
 
493
  /// Set starting location of directive kind.
494
  ///
495
  /// \param Loc New starting location of directive.
496
  ///
497
  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
498
  /// Set ending location of directive.
499
  ///
500
  /// \param Loc New ending location of directive.
501
  ///
502
  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
503
 
504
  /// Get number of clauses.
505
  unsigned getNumClauses() const {
506
    if (!Data)
507
      return 0;
508
    return Data->getNumClauses();
509
  }
510
 
511
  /// Returns specified clause.
512
  ///
513
  /// \param I Number of clause.
514
  ///
515
  OMPClause *getClause(unsigned I) const { return clauses()[I]; }
516
 
517
  /// Returns true if directive has associated statement.
518
  bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
519
 
520
  /// Returns statement associated with the directive.
521
  const Stmt *getAssociatedStmt() const {
522
    return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
523
  }
524
  Stmt *getAssociatedStmt() {
525
    assert(hasAssociatedStmt() &&
526
           "Expected directive with the associated statement.");
527
    return Data->getAssociatedStmt();
528
  }
529
 
530
  /// Returns the captured statement associated with the
531
  /// component region within the (combined) directive.
532
  ///
533
  /// \param RegionKind Component region kind.
534
  const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
535
    assert(hasAssociatedStmt() &&
536
           "Expected directive with the associated statement.");
537
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
538
    getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
539
    return Data->getCapturedStmt(RegionKind, CaptureRegions);
540
  }
541
 
542
  /// Get innermost captured statement for the construct.
543
  CapturedStmt *getInnermostCapturedStmt() {
544
    assert(hasAssociatedStmt() &&
545
           "Expected directive with the associated statement.");
546
    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
547
    getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
548
    return Data->getInnermostCapturedStmt(CaptureRegions);
549
  }
550
 
551
  const CapturedStmt *getInnermostCapturedStmt() const {
552
    return const_cast<OMPExecutableDirective *>(this)
553
        ->getInnermostCapturedStmt();
554
  }
555
 
556
  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
557
 
558
  static bool classof(const Stmt *S) {
559
    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
560
           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
561
  }
562
 
563
  child_range children() {
564
    if (!Data)
565
      return child_range(child_iterator(), child_iterator());
566
    return Data->getAssociatedStmtAsRange();
567
  }
568
 
569
  const_child_range children() const {
570
    return const_cast<OMPExecutableDirective *>(this)->children();
571
  }
572
 
573
  ArrayRef<OMPClause *> clauses() const {
574
    if (!Data)
575
      return std::nullopt;
576
    return Data->getClauses();
577
  }
578
 
579
  /// Returns whether or not this is a Standalone directive.
580
  ///
581
  /// Stand-alone directives are executable directives
582
  /// that have no associated user code.
583
  bool isStandaloneDirective() const;
584
 
585
  /// Returns the AST node representing OpenMP structured-block of this
586
  /// OpenMP executable directive,
587
  /// Prerequisite: Executable Directive must not be Standalone directive.
588
  const Stmt *getStructuredBlock() const {
589
    return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
590
  }
591
  Stmt *getStructuredBlock();
592
 
593
  const Stmt *getRawStmt() const {
594
    return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
595
  }
596
  Stmt *getRawStmt() {
597
    assert(hasAssociatedStmt() &&
598
           "Expected directive with the associated statement.");
599
    return Data->getRawStmt();
600
  }
601
};
602
 
603
/// This represents '#pragma omp parallel' directive.
604
///
605
/// \code
606
/// #pragma omp parallel private(a,b) reduction(+: c,d)
607
/// \endcode
608
/// In this example directive '#pragma omp parallel' has clauses 'private'
609
/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
610
/// variables 'c' and 'd'.
611
///
612
class OMPParallelDirective : public OMPExecutableDirective {
613
  friend class ASTStmtReader;
614
  friend class OMPExecutableDirective;
615
  /// true if the construct has inner cancel directive.
616
  bool HasCancel = false;
617
 
618
  /// Build directive with the given start and end location.
619
  ///
620
  /// \param StartLoc Starting location of the directive (directive keyword).
621
  /// \param EndLoc Ending Location of the directive.
622
  ///
623
  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
624
      : OMPExecutableDirective(OMPParallelDirectiveClass,
625
                               llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
626
 
627
  /// Build an empty directive.
628
  ///
629
  explicit OMPParallelDirective()
630
      : OMPExecutableDirective(OMPParallelDirectiveClass,
631
                               llvm::omp::OMPD_parallel, SourceLocation(),
632
                               SourceLocation()) {}
633
 
634
  /// Sets special task reduction descriptor.
635
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
636
 
637
  /// Set cancel state.
638
  void setHasCancel(bool Has) { HasCancel = Has; }
639
 
640
public:
641
  /// Creates directive with a list of \a Clauses.
642
  ///
643
  /// \param C AST context.
644
  /// \param StartLoc Starting location of the directive kind.
645
  /// \param EndLoc Ending Location of the directive.
646
  /// \param Clauses List of clauses.
647
  /// \param AssociatedStmt Statement associated with the directive.
648
  /// \param TaskRedRef Task reduction special reference expression to handle
649
  /// taskgroup descriptor.
650
  /// \param HasCancel true if this directive has inner cancel directive.
651
  ///
652
  static OMPParallelDirective *
653
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
654
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
655
         bool HasCancel);
656
 
657
  /// Creates an empty directive with the place for \a N clauses.
658
  ///
659
  /// \param C AST context.
660
  /// \param NumClauses Number of clauses.
661
  ///
662
  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
663
                                           unsigned NumClauses, EmptyShell);
664
 
665
  /// Returns special task reduction reference expression.
666
  Expr *getTaskReductionRefExpr() {
667
    return cast_or_null<Expr>(Data->getChildren()[0]);
668
  }
669
  const Expr *getTaskReductionRefExpr() const {
670
    return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
671
  }
672
 
673
  /// Return true if current directive has inner cancel directive.
674
  bool hasCancel() const { return HasCancel; }
675
 
676
  static bool classof(const Stmt *T) {
677
    return T->getStmtClass() == OMPParallelDirectiveClass;
678
  }
679
};
680
 
681
/// The base class for all loop-based directives, including loop transformation
682
/// directives.
683
class OMPLoopBasedDirective : public OMPExecutableDirective {
684
  friend class ASTStmtReader;
685
 
686
protected:
687
  /// Number of collapsed loops as specified by 'collapse' clause.
688
  unsigned NumAssociatedLoops = 0;
689
 
690
  /// Build instance of loop directive of class \a Kind.
691
  ///
692
  /// \param SC Statement class.
693
  /// \param Kind Kind of OpenMP directive.
694
  /// \param StartLoc Starting location of the directive (directive keyword).
695
  /// \param EndLoc Ending location of the directive.
696
  /// \param NumAssociatedLoops Number of loops associated with the construct.
697
  ///
698
  OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind,
699
                        SourceLocation StartLoc, SourceLocation EndLoc,
700
                        unsigned NumAssociatedLoops)
701
      : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
702
        NumAssociatedLoops(NumAssociatedLoops) {}
703
 
704
public:
705
  /// The expressions built to support OpenMP loops in combined/composite
706
  /// pragmas (e.g. pragma omp distribute parallel for)
707
  struct DistCombinedHelperExprs {
708
    /// DistributeLowerBound - used when composing 'omp distribute' with
709
    /// 'omp for' in a same construct.
710
    Expr *LB;
711
    /// DistributeUpperBound - used when composing 'omp distribute' with
712
    /// 'omp for' in a same construct.
713
    Expr *UB;
714
    /// DistributeEnsureUpperBound - used when composing 'omp distribute'
715
    ///  with 'omp for' in a same construct, EUB depends on DistUB
716
    Expr *EUB;
717
    /// Distribute loop iteration variable init used when composing 'omp
718
    /// distribute'
719
    ///  with 'omp for' in a same construct
720
    Expr *Init;
721
    /// Distribute Loop condition used when composing 'omp distribute'
722
    ///  with 'omp for' in a same construct
723
    Expr *Cond;
724
    /// Update of LowerBound for statically scheduled omp loops for
725
    /// outer loop in combined constructs (e.g. 'distribute parallel for')
726
    Expr *NLB;
727
    /// Update of UpperBound for statically scheduled omp loops for
728
    /// outer loop in combined constructs (e.g. 'distribute parallel for')
729
    Expr *NUB;
730
    /// Distribute Loop condition used when composing 'omp distribute'
731
    ///  with 'omp for' in a same construct when schedule is chunked.
732
    Expr *DistCond;
733
    /// 'omp parallel for' loop condition used when composed with
734
    /// 'omp distribute' in the same construct and when schedule is
735
    /// chunked and the chunk size is 1.
736
    Expr *ParForInDistCond;
737
  };
738
 
739
  /// The expressions built for the OpenMP loop CodeGen for the
740
  /// whole collapsed loop nest.
741
  struct HelperExprs {
742
    /// Loop iteration variable.
743
    Expr *IterationVarRef;
744
    /// Loop last iteration number.
745
    Expr *LastIteration;
746
    /// Loop number of iterations.
747
    Expr *NumIterations;
748
    /// Calculation of last iteration.
749
    Expr *CalcLastIteration;
750
    /// Loop pre-condition.
751
    Expr *PreCond;
752
    /// Loop condition.
753
    Expr *Cond;
754
    /// Loop iteration variable init.
755
    Expr *Init;
756
    /// Loop increment.
757
    Expr *Inc;
758
    /// IsLastIteration - local flag variable passed to runtime.
759
    Expr *IL;
760
    /// LowerBound - local variable passed to runtime.
761
    Expr *LB;
762
    /// UpperBound - local variable passed to runtime.
763
    Expr *UB;
764
    /// Stride - local variable passed to runtime.
765
    Expr *ST;
766
    /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
767
    Expr *EUB;
768
    /// Update of LowerBound for statically scheduled 'omp for' loops.
769
    Expr *NLB;
770
    /// Update of UpperBound for statically scheduled 'omp for' loops.
771
    Expr *NUB;
772
    /// PreviousLowerBound - local variable passed to runtime in the
773
    /// enclosing schedule or null if that does not apply.
774
    Expr *PrevLB;
775
    /// PreviousUpperBound - local variable passed to runtime in the
776
    /// enclosing schedule or null if that does not apply.
777
    Expr *PrevUB;
778
    /// DistInc - increment expression for distribute loop when found
779
    /// combined with a further loop level (e.g. in 'distribute parallel for')
780
    /// expression IV = IV + ST
781
    Expr *DistInc;
782
    /// PrevEUB - expression similar to EUB but to be used when loop
783
    /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
784
    /// when ensuring that the UB is either the calculated UB by the runtime or
785
    /// the end of the assigned distribute chunk)
786
    /// expression UB = min (UB, PrevUB)
787
    Expr *PrevEUB;
788
    /// Counters Loop counters.
789
    SmallVector<Expr *, 4> Counters;
790
    /// PrivateCounters Loop counters.
791
    SmallVector<Expr *, 4> PrivateCounters;
792
    /// Expressions for loop counters inits for CodeGen.
793
    SmallVector<Expr *, 4> Inits;
794
    /// Expressions for loop counters update for CodeGen.
795
    SmallVector<Expr *, 4> Updates;
796
    /// Final loop counter values for GodeGen.
797
    SmallVector<Expr *, 4> Finals;
798
    /// List of counters required for the generation of the non-rectangular
799
    /// loops.
800
    SmallVector<Expr *, 4> DependentCounters;
801
    /// List of initializers required for the generation of the non-rectangular
802
    /// loops.
803
    SmallVector<Expr *, 4> DependentInits;
804
    /// List of final conditions required for the generation of the
805
    /// non-rectangular loops.
806
    SmallVector<Expr *, 4> FinalsConditions;
807
    /// Init statement for all captured expressions.
808
    Stmt *PreInits;
809
 
810
    /// Expressions used when combining OpenMP loop pragmas
811
    DistCombinedHelperExprs DistCombinedFields;
812
 
813
    /// Check if all the expressions are built (does not check the
814
    /// worksharing ones).
815
    bool builtAll() {
816
      return IterationVarRef != nullptr && LastIteration != nullptr &&
817
             NumIterations != nullptr && PreCond != nullptr &&
818
             Cond != nullptr && Init != nullptr && Inc != nullptr;
819
    }
820
 
821
    /// Initialize all the fields to null.
822
    /// \param Size Number of elements in the
823
    /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
824
    /// arrays.
825
    void clear(unsigned Size) {
826
      IterationVarRef = nullptr;
827
      LastIteration = nullptr;
828
      CalcLastIteration = nullptr;
829
      PreCond = nullptr;
830
      Cond = nullptr;
831
      Init = nullptr;
832
      Inc = nullptr;
833
      IL = nullptr;
834
      LB = nullptr;
835
      UB = nullptr;
836
      ST = nullptr;
837
      EUB = nullptr;
838
      NLB = nullptr;
839
      NUB = nullptr;
840
      NumIterations = nullptr;
841
      PrevLB = nullptr;
842
      PrevUB = nullptr;
843
      DistInc = nullptr;
844
      PrevEUB = nullptr;
845
      Counters.resize(Size);
846
      PrivateCounters.resize(Size);
847
      Inits.resize(Size);
848
      Updates.resize(Size);
849
      Finals.resize(Size);
850
      DependentCounters.resize(Size);
851
      DependentInits.resize(Size);
852
      FinalsConditions.resize(Size);
853
      for (unsigned I = 0; I < Size; ++I) {
854
        Counters[I] = nullptr;
855
        PrivateCounters[I] = nullptr;
856
        Inits[I] = nullptr;
857
        Updates[I] = nullptr;
858
        Finals[I] = nullptr;
859
        DependentCounters[I] = nullptr;
860
        DependentInits[I] = nullptr;
861
        FinalsConditions[I] = nullptr;
862
      }
863
      PreInits = nullptr;
864
      DistCombinedFields.LB = nullptr;
865
      DistCombinedFields.UB = nullptr;
866
      DistCombinedFields.EUB = nullptr;
867
      DistCombinedFields.Init = nullptr;
868
      DistCombinedFields.Cond = nullptr;
869
      DistCombinedFields.NLB = nullptr;
870
      DistCombinedFields.NUB = nullptr;
871
      DistCombinedFields.DistCond = nullptr;
872
      DistCombinedFields.ParForInDistCond = nullptr;
873
    }
874
  };
875
 
876
  /// Get number of collapsed loops.
877
  unsigned getLoopsNumber() const { return NumAssociatedLoops; }
878
 
879
  /// Try to find the next loop sub-statement in the specified statement \p
880
  /// CurStmt.
881
  /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
882
  /// imperfectly nested loop.
883
  static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
884
                                      bool TryImperfectlyNestedLoops);
885
  static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
886
                                            bool TryImperfectlyNestedLoops) {
887
    return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
888
                                  TryImperfectlyNestedLoops);
889
  }
890
 
891
  /// Calls the specified callback function for all the loops in \p CurStmt,
892
  /// from the outermost to the innermost.
893
  static bool
894
  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
895
                unsigned NumLoops,
896
                llvm::function_ref<bool(unsigned, Stmt *)> Callback,
897
                llvm::function_ref<void(OMPLoopTransformationDirective *)>
898
                    OnTransformationCallback);
899
  static bool
900
  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
901
                unsigned NumLoops,
902
                llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
903
                llvm::function_ref<void(const OMPLoopTransformationDirective *)>
904
                    OnTransformationCallback) {
905
    auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
906
      return Callback(Cnt, CurStmt);
907
    };
908
    auto &&NewTransformCb =
909
        [OnTransformationCallback](OMPLoopTransformationDirective *A) {
910
          OnTransformationCallback(A);
911
        };
912
    return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
913
                         NumLoops, NewCallback, NewTransformCb);
914
  }
915
 
916
  /// Calls the specified callback function for all the loops in \p CurStmt,
917
  /// from the outermost to the innermost.
918
  static bool
919
  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
920
                unsigned NumLoops,
921
                llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
922
    auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
923
    return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
924
                         TransformCb);
925
  }
926
  static bool
927
  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
928
                unsigned NumLoops,
929
                llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
930
    auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
931
      return Callback(Cnt, CurStmt);
932
    };
933
    return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
934
                         NumLoops, NewCallback);
935
  }
936
 
937
  /// Calls the specified callback function for all the loop bodies in \p
938
  /// CurStmt, from the outermost loop to the innermost.
939
  static void doForAllLoopsBodies(
940
      Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
941
      llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
942
  static void doForAllLoopsBodies(
943
      const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
944
      llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
945
    auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
946
      Callback(Cnt, Loop, Body);
947
    };
948
    doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949
                        NumLoops, NewCallback);
950
  }
951
 
952
  static bool classof(const Stmt *T) {
953
    if (auto *D = dyn_cast<OMPExecutableDirective>(T))
954
      return isOpenMPLoopDirective(D->getDirectiveKind());
955
    return false;
956
  }
957
};
958
 
959
/// The base class for all loop transformation directives.
960
class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
961
  friend class ASTStmtReader;
962
 
963
  /// Number of loops generated by this loop transformation.
964
  unsigned NumGeneratedLoops = 0;
965
 
966
protected:
967
  explicit OMPLoopTransformationDirective(StmtClass SC,
968
                                          OpenMPDirectiveKind Kind,
969
                                          SourceLocation StartLoc,
970
                                          SourceLocation EndLoc,
971
                                          unsigned NumAssociatedLoops)
972
      : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
973
 
974
  /// Set the number of loops generated by this loop transformation.
975
  void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
976
 
977
public:
978
  /// Return the number of associated (consumed) loops.
979
  unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
980
 
981
  /// Return the number of loops generated by this loop transformation.
982
  unsigned getNumGeneratedLoops() { return NumGeneratedLoops; }
983
 
984
  /// Get the de-sugared statements after the loop transformation.
985
  ///
986
  /// Might be nullptr if either the directive generates no loops and is handled
987
  /// directly in CodeGen, or resolving a template-dependence context is
988
  /// required.
989
  Stmt *getTransformedStmt() const;
990
 
991
  /// Return preinits statement.
992
  Stmt *getPreInits() const;
993
 
994
  static bool classof(const Stmt *T) {
995
    return T->getStmtClass() == OMPTileDirectiveClass ||
996
           T->getStmtClass() == OMPUnrollDirectiveClass;
997
  }
998
};
999
 
1000
/// This is a common base class for loop directives ('omp simd', 'omp
1001
/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1002
///
1003
class OMPLoopDirective : public OMPLoopBasedDirective {
1004
  friend class ASTStmtReader;
1005
 
1006
  /// Offsets to the stored exprs.
1007
  /// This enumeration contains offsets to all the pointers to children
1008
  /// expressions stored in OMPLoopDirective.
1009
  /// The first 9 children are necessary for all the loop directives,
1010
  /// the next 8 are specific to the worksharing ones, and the next 11 are
1011
  /// used for combined constructs containing two pragmas associated to loops.
1012
  /// After the fixed children, three arrays of length NumAssociatedLoops are
1013
  /// allocated: loop counters, their updates and final values.
1014
  /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1015
  /// information in composite constructs which require loop blocking
1016
  /// DistInc is used to generate the increment expression for the distribute
1017
  /// loop when combined with a further nested loop
1018
  /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1019
  /// for loop when combined with a previous distribute loop in the same pragma
1020
  /// (e.g. 'distribute parallel for')
1021
  ///
1022
  enum {
1023
    IterationVariableOffset = 0,
1024
    LastIterationOffset = 1,
1025
    CalcLastIterationOffset = 2,
1026
    PreConditionOffset = 3,
1027
    CondOffset = 4,
1028
    InitOffset = 5,
1029
    IncOffset = 6,
1030
    PreInitsOffset = 7,
1031
    // The '...End' enumerators do not correspond to child expressions - they
1032
    // specify the offset to the end (and start of the following counters/
1033
    // updates/finals/dependent_counters/dependent_inits/finals_conditions
1034
    // arrays).
1035
    DefaultEnd = 8,
1036
    // The following 8 exprs are used by worksharing and distribute loops only.
1037
    IsLastIterVariableOffset = 8,
1038
    LowerBoundVariableOffset = 9,
1039
    UpperBoundVariableOffset = 10,
1040
    StrideVariableOffset = 11,
1041
    EnsureUpperBoundOffset = 12,
1042
    NextLowerBoundOffset = 13,
1043
    NextUpperBoundOffset = 14,
1044
    NumIterationsOffset = 15,
1045
    // Offset to the end for worksharing loop directives.
1046
    WorksharingEnd = 16,
1047
    PrevLowerBoundVariableOffset = 16,
1048
    PrevUpperBoundVariableOffset = 17,
1049
    DistIncOffset = 18,
1050
    PrevEnsureUpperBoundOffset = 19,
1051
    CombinedLowerBoundVariableOffset = 20,
1052
    CombinedUpperBoundVariableOffset = 21,
1053
    CombinedEnsureUpperBoundOffset = 22,
1054
    CombinedInitOffset = 23,
1055
    CombinedConditionOffset = 24,
1056
    CombinedNextLowerBoundOffset = 25,
1057
    CombinedNextUpperBoundOffset = 26,
1058
    CombinedDistConditionOffset = 27,
1059
    CombinedParForInDistConditionOffset = 28,
1060
    // Offset to the end (and start of the following
1061
    // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1062
    // arrays) for combined distribute loop directives.
1063
    CombinedDistributeEnd = 29,
1064
  };
1065
 
1066
  /// Get the counters storage.
1067
  MutableArrayRef<Expr *> getCounters() {
1068
    auto **Storage = reinterpret_cast<Expr **>(
1069
        &Data->getChildren()[getArraysOffset(getDirectiveKind())]);
1070
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1071
  }
1072
 
1073
  /// Get the private counters storage.
1074
  MutableArrayRef<Expr *> getPrivateCounters() {
1075
    auto **Storage = reinterpret_cast<Expr **>(
1076
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1077
                             getLoopsNumber()]);
1078
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1079
  }
1080
 
1081
  /// Get the updates storage.
1082
  MutableArrayRef<Expr *> getInits() {
1083
    auto **Storage = reinterpret_cast<Expr **>(
1084
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1085
                             2 * getLoopsNumber()]);
1086
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1087
  }
1088
 
1089
  /// Get the updates storage.
1090
  MutableArrayRef<Expr *> getUpdates() {
1091
    auto **Storage = reinterpret_cast<Expr **>(
1092
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1093
                             3 * getLoopsNumber()]);
1094
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1095
  }
1096
 
1097
  /// Get the final counter updates storage.
1098
  MutableArrayRef<Expr *> getFinals() {
1099
    auto **Storage = reinterpret_cast<Expr **>(
1100
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1101
                             4 * getLoopsNumber()]);
1102
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1103
  }
1104
 
1105
  /// Get the dependent counters storage.
1106
  MutableArrayRef<Expr *> getDependentCounters() {
1107
    auto **Storage = reinterpret_cast<Expr **>(
1108
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1109
                             5 * getLoopsNumber()]);
1110
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1111
  }
1112
 
1113
  /// Get the dependent inits storage.
1114
  MutableArrayRef<Expr *> getDependentInits() {
1115
    auto **Storage = reinterpret_cast<Expr **>(
1116
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1117
                             6 * getLoopsNumber()]);
1118
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1119
  }
1120
 
1121
  /// Get the finals conditions storage.
1122
  MutableArrayRef<Expr *> getFinalsConditions() {
1123
    auto **Storage = reinterpret_cast<Expr **>(
1124
        &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1125
                             7 * getLoopsNumber()]);
1126
    return llvm::MutableArrayRef(Storage, getLoopsNumber());
1127
  }
1128
 
1129
protected:
1130
  /// Build instance of loop directive of class \a Kind.
1131
  ///
1132
  /// \param SC Statement class.
1133
  /// \param Kind Kind of OpenMP directive.
1134
  /// \param StartLoc Starting location of the directive (directive keyword).
1135
  /// \param EndLoc Ending location of the directive.
1136
  /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1137
  ///
1138
  OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind,
1139
                   SourceLocation StartLoc, SourceLocation EndLoc,
1140
                   unsigned CollapsedNum)
1141
      : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1142
 
1143
  /// Offset to the start of children expression arrays.
1144
  static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
1145
    if (isOpenMPLoopBoundSharingDirective(Kind))
1146
      return CombinedDistributeEnd;
1147
    if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
1148
        isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
1149
      return WorksharingEnd;
1150
    return DefaultEnd;
1151
  }
1152
 
1153
  /// Children number.
1154
  static unsigned numLoopChildren(unsigned CollapsedNum,
1155
                                  OpenMPDirectiveKind Kind) {
1156
    return getArraysOffset(Kind) +
1157
           8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1158
                             // Updates, Finals, DependentCounters,
1159
                             // DependentInits, FinalsConditions.
1160
  }
1161
 
1162
  void setIterationVariable(Expr *IV) {
1163
    Data->getChildren()[IterationVariableOffset] = IV;
1164
  }
1165
  void setLastIteration(Expr *LI) {
1166
    Data->getChildren()[LastIterationOffset] = LI;
1167
  }
1168
  void setCalcLastIteration(Expr *CLI) {
1169
    Data->getChildren()[CalcLastIterationOffset] = CLI;
1170
  }
1171
  void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1172
  void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1173
  void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1174
  void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1175
  void setPreInits(Stmt *PreInits) {
1176
    Data->getChildren()[PreInitsOffset] = PreInits;
1177
  }
1178
  void setIsLastIterVariable(Expr *IL) {
1179
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1180
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1181
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1182
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1183
           "expected worksharing loop directive");
1184
    Data->getChildren()[IsLastIterVariableOffset] = IL;
1185
  }
1186
  void setLowerBoundVariable(Expr *LB) {
1187
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1188
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1189
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1190
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1191
           "expected worksharing loop directive");
1192
    Data->getChildren()[LowerBoundVariableOffset] = LB;
1193
  }
1194
  void setUpperBoundVariable(Expr *UB) {
1195
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1196
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1197
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1198
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1199
           "expected worksharing loop directive");
1200
    Data->getChildren()[UpperBoundVariableOffset] = UB;
1201
  }
1202
  void setStrideVariable(Expr *ST) {
1203
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1204
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1205
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1206
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1207
           "expected worksharing loop directive");
1208
    Data->getChildren()[StrideVariableOffset] = ST;
1209
  }
1210
  void setEnsureUpperBound(Expr *EUB) {
1211
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1212
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1213
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1214
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1215
           "expected worksharing loop directive");
1216
    Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1217
  }
1218
  void setNextLowerBound(Expr *NLB) {
1219
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1220
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1221
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1222
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1223
           "expected worksharing loop directive");
1224
    Data->getChildren()[NextLowerBoundOffset] = NLB;
1225
  }
1226
  void setNextUpperBound(Expr *NUB) {
1227
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1228
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1229
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1230
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1231
           "expected worksharing loop directive");
1232
    Data->getChildren()[NextUpperBoundOffset] = NUB;
1233
  }
1234
  void setNumIterations(Expr *NI) {
1235
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1236
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1237
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1238
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1239
           "expected worksharing loop directive");
1240
    Data->getChildren()[NumIterationsOffset] = NI;
1241
  }
1242
  void setPrevLowerBoundVariable(Expr *PrevLB) {
1243
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1244
           "expected loop bound sharing directive");
1245
    Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1246
  }
1247
  void setPrevUpperBoundVariable(Expr *PrevUB) {
1248
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1249
           "expected loop bound sharing directive");
1250
    Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1251
  }
1252
  void setDistInc(Expr *DistInc) {
1253
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1254
           "expected loop bound sharing directive");
1255
    Data->getChildren()[DistIncOffset] = DistInc;
1256
  }
1257
  void setPrevEnsureUpperBound(Expr *PrevEUB) {
1258
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1259
           "expected loop bound sharing directive");
1260
    Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1261
  }
1262
  void setCombinedLowerBoundVariable(Expr *CombLB) {
1263
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1264
           "expected loop bound sharing directive");
1265
    Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1266
  }
1267
  void setCombinedUpperBoundVariable(Expr *CombUB) {
1268
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1269
           "expected loop bound sharing directive");
1270
    Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1271
  }
1272
  void setCombinedEnsureUpperBound(Expr *CombEUB) {
1273
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1274
           "expected loop bound sharing directive");
1275
    Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1276
  }
1277
  void setCombinedInit(Expr *CombInit) {
1278
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1279
           "expected loop bound sharing directive");
1280
    Data->getChildren()[CombinedInitOffset] = CombInit;
1281
  }
1282
  void setCombinedCond(Expr *CombCond) {
1283
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1284
           "expected loop bound sharing directive");
1285
    Data->getChildren()[CombinedConditionOffset] = CombCond;
1286
  }
1287
  void setCombinedNextLowerBound(Expr *CombNLB) {
1288
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1289
           "expected loop bound sharing directive");
1290
    Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1291
  }
1292
  void setCombinedNextUpperBound(Expr *CombNUB) {
1293
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1294
           "expected loop bound sharing directive");
1295
    Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1296
  }
1297
  void setCombinedDistCond(Expr *CombDistCond) {
1298
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1299
           "expected loop bound distribute sharing directive");
1300
    Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1301
  }
1302
  void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1303
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1304
           "expected loop bound distribute sharing directive");
1305
    Data->getChildren()[CombinedParForInDistConditionOffset] =
1306
        CombParForInDistCond;
1307
  }
1308
  void setCounters(ArrayRef<Expr *> A);
1309
  void setPrivateCounters(ArrayRef<Expr *> A);
1310
  void setInits(ArrayRef<Expr *> A);
1311
  void setUpdates(ArrayRef<Expr *> A);
1312
  void setFinals(ArrayRef<Expr *> A);
1313
  void setDependentCounters(ArrayRef<Expr *> A);
1314
  void setDependentInits(ArrayRef<Expr *> A);
1315
  void setFinalsConditions(ArrayRef<Expr *> A);
1316
 
1317
public:
1318
  Expr *getIterationVariable() const {
1319
    return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1320
  }
1321
  Expr *getLastIteration() const {
1322
    return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1323
  }
1324
  Expr *getCalcLastIteration() const {
1325
    return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1326
  }
1327
  Expr *getPreCond() const {
1328
    return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1329
  }
1330
  Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1331
  Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1332
  Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1333
  const Stmt *getPreInits() const {
1334
    return Data->getChildren()[PreInitsOffset];
1335
  }
1336
  Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1337
  Expr *getIsLastIterVariable() const {
1338
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1339
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1340
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1341
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1342
           "expected worksharing loop directive");
1343
    return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1344
  }
1345
  Expr *getLowerBoundVariable() const {
1346
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1347
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1348
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1349
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1350
           "expected worksharing loop directive");
1351
    return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1352
  }
1353
  Expr *getUpperBoundVariable() const {
1354
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1355
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1356
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1357
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1358
           "expected worksharing loop directive");
1359
    return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1360
  }
1361
  Expr *getStrideVariable() const {
1362
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1363
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1364
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1365
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1366
           "expected worksharing loop directive");
1367
    return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1368
  }
1369
  Expr *getEnsureUpperBound() const {
1370
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1371
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1372
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1373
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1374
           "expected worksharing loop directive");
1375
    return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1376
  }
1377
  Expr *getNextLowerBound() const {
1378
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1379
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1380
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1381
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1382
           "expected worksharing loop directive");
1383
    return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1384
  }
1385
  Expr *getNextUpperBound() const {
1386
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1387
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1388
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1389
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1390
           "expected worksharing loop directive");
1391
    return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1392
  }
1393
  Expr *getNumIterations() const {
1394
    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1395
            isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1396
            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1397
            isOpenMPDistributeDirective(getDirectiveKind())) &&
1398
           "expected worksharing loop directive");
1399
    return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1400
  }
1401
  Expr *getPrevLowerBoundVariable() const {
1402
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1403
           "expected loop bound sharing directive");
1404
    return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1405
  }
1406
  Expr *getPrevUpperBoundVariable() const {
1407
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1408
           "expected loop bound sharing directive");
1409
    return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1410
  }
1411
  Expr *getDistInc() const {
1412
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1413
           "expected loop bound sharing directive");
1414
    return cast<Expr>(Data->getChildren()[DistIncOffset]);
1415
  }
1416
  Expr *getPrevEnsureUpperBound() const {
1417
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1418
           "expected loop bound sharing directive");
1419
    return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1420
  }
1421
  Expr *getCombinedLowerBoundVariable() const {
1422
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1423
           "expected loop bound sharing directive");
1424
    return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1425
  }
1426
  Expr *getCombinedUpperBoundVariable() const {
1427
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1428
           "expected loop bound sharing directive");
1429
    return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1430
  }
1431
  Expr *getCombinedEnsureUpperBound() const {
1432
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1433
           "expected loop bound sharing directive");
1434
    return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1435
  }
1436
  Expr *getCombinedInit() const {
1437
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1438
           "expected loop bound sharing directive");
1439
    return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1440
  }
1441
  Expr *getCombinedCond() const {
1442
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1443
           "expected loop bound sharing directive");
1444
    return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1445
  }
1446
  Expr *getCombinedNextLowerBound() const {
1447
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1448
           "expected loop bound sharing directive");
1449
    return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1450
  }
1451
  Expr *getCombinedNextUpperBound() const {
1452
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1453
           "expected loop bound sharing directive");
1454
    return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1455
  }
1456
  Expr *getCombinedDistCond() const {
1457
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1458
           "expected loop bound distribute sharing directive");
1459
    return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1460
  }
1461
  Expr *getCombinedParForInDistCond() const {
1462
    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1463
           "expected loop bound distribute sharing directive");
1464
    return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1465
  }
1466
  Stmt *getBody();
1467
  const Stmt *getBody() const {
1468
    return const_cast<OMPLoopDirective *>(this)->getBody();
1469
  }
1470
 
1471
  ArrayRef<Expr *> counters() { return getCounters(); }
1472
 
1473
  ArrayRef<Expr *> counters() const {
1474
    return const_cast<OMPLoopDirective *>(this)->getCounters();
1475
  }
1476
 
1477
  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1478
 
1479
  ArrayRef<Expr *> private_counters() const {
1480
    return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1481
  }
1482
 
1483
  ArrayRef<Expr *> inits() { return getInits(); }
1484
 
1485
  ArrayRef<Expr *> inits() const {
1486
    return const_cast<OMPLoopDirective *>(this)->getInits();
1487
  }
1488
 
1489
  ArrayRef<Expr *> updates() { return getUpdates(); }
1490
 
1491
  ArrayRef<Expr *> updates() const {
1492
    return const_cast<OMPLoopDirective *>(this)->getUpdates();
1493
  }
1494
 
1495
  ArrayRef<Expr *> finals() { return getFinals(); }
1496
 
1497
  ArrayRef<Expr *> finals() const {
1498
    return const_cast<OMPLoopDirective *>(this)->getFinals();
1499
  }
1500
 
1501
  ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1502
 
1503
  ArrayRef<Expr *> dependent_counters() const {
1504
    return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1505
  }
1506
 
1507
  ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1508
 
1509
  ArrayRef<Expr *> dependent_inits() const {
1510
    return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1511
  }
1512
 
1513
  ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1514
 
1515
  ArrayRef<Expr *> finals_conditions() const {
1516
    return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1517
  }
1518
 
1519
  static bool classof(const Stmt *T) {
1520
    return T->getStmtClass() == OMPSimdDirectiveClass ||
1521
           T->getStmtClass() == OMPForDirectiveClass ||
1522
           T->getStmtClass() == OMPForSimdDirectiveClass ||
1523
           T->getStmtClass() == OMPParallelForDirectiveClass ||
1524
           T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1525
           T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1526
           T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1527
           T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1528
           T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1529
           T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1530
           T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1531
           T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1532
           T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1533
           T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1534
           T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1535
           T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1536
           T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1537
           T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1538
           T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1539
           T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1540
           T->getStmtClass() == OMPDistributeDirectiveClass ||
1541
           T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1542
           T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1543
           T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1544
           T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1545
           T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1546
           T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1547
           T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1548
           T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1549
           T->getStmtClass() ==
1550
               OMPTeamsDistributeParallelForSimdDirectiveClass ||
1551
           T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1552
           T->getStmtClass() ==
1553
               OMPTargetTeamsDistributeParallelForDirectiveClass ||
1554
           T->getStmtClass() ==
1555
               OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1556
           T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1557
           T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1558
  }
1559
};
1560
 
1561
/// This represents '#pragma omp simd' directive.
1562
///
1563
/// \code
1564
/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1565
/// \endcode
1566
/// In this example directive '#pragma omp simd' has clauses 'private'
1567
/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1568
/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1569
///
1570
class OMPSimdDirective : public OMPLoopDirective {
1571
  friend class ASTStmtReader;
1572
  friend class OMPExecutableDirective;
1573
  /// Build directive with the given start and end location.
1574
  ///
1575
  /// \param StartLoc Starting location of the directive kind.
1576
  /// \param EndLoc Ending location of the directive.
1577
  /// \param CollapsedNum Number of collapsed nested loops.
1578
  ///
1579
  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1580
                   unsigned CollapsedNum)
1581
      : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1582
                         EndLoc, CollapsedNum) {}
1583
 
1584
  /// Build an empty directive.
1585
  ///
1586
  /// \param CollapsedNum Number of collapsed nested loops.
1587
  ///
1588
  explicit OMPSimdDirective(unsigned CollapsedNum)
1589
      : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1590
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
1591
 
1592
public:
1593
  /// Creates directive with a list of \a Clauses.
1594
  ///
1595
  /// \param C AST context.
1596
  /// \param StartLoc Starting location of the directive kind.
1597
  /// \param EndLoc Ending Location of the directive.
1598
  /// \param CollapsedNum Number of collapsed loops.
1599
  /// \param Clauses List of clauses.
1600
  /// \param AssociatedStmt Statement, associated with the directive.
1601
  /// \param Exprs Helper expressions for CodeGen.
1602
  ///
1603
  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1604
                                  SourceLocation EndLoc, unsigned CollapsedNum,
1605
                                  ArrayRef<OMPClause *> Clauses,
1606
                                  Stmt *AssociatedStmt,
1607
                                  const HelperExprs &Exprs);
1608
 
1609
  /// Creates an empty directive with the place
1610
  /// for \a NumClauses clauses.
1611
  ///
1612
  /// \param C AST context.
1613
  /// \param CollapsedNum Number of collapsed nested loops.
1614
  /// \param NumClauses Number of clauses.
1615
  ///
1616
  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1617
                                       unsigned CollapsedNum, EmptyShell);
1618
 
1619
  static bool classof(const Stmt *T) {
1620
    return T->getStmtClass() == OMPSimdDirectiveClass;
1621
  }
1622
};
1623
 
1624
/// This represents '#pragma omp for' directive.
1625
///
1626
/// \code
1627
/// #pragma omp for private(a,b) reduction(+:c,d)
1628
/// \endcode
1629
/// In this example directive '#pragma omp for' has clauses 'private' with the
1630
/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1631
/// and 'd'.
1632
///
1633
class OMPForDirective : public OMPLoopDirective {
1634
  friend class ASTStmtReader;
1635
  friend class OMPExecutableDirective;
1636
  /// true if current directive has inner cancel directive.
1637
  bool HasCancel = false;
1638
 
1639
  /// Build directive with the given start and end location.
1640
  ///
1641
  /// \param StartLoc Starting location of the directive kind.
1642
  /// \param EndLoc Ending location of the directive.
1643
  /// \param CollapsedNum Number of collapsed nested loops.
1644
  ///
1645
  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1646
                  unsigned CollapsedNum)
1647
      : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1648
                         EndLoc, CollapsedNum) {}
1649
 
1650
  /// Build an empty directive.
1651
  ///
1652
  /// \param CollapsedNum Number of collapsed nested loops.
1653
  ///
1654
  explicit OMPForDirective(unsigned CollapsedNum)
1655
      : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1656
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
1657
 
1658
  /// Sets special task reduction descriptor.
1659
  void setTaskReductionRefExpr(Expr *E) {
1660
    Data->getChildren()[numLoopChildren(getLoopsNumber(),
1661
                                        llvm::omp::OMPD_for)] = E;
1662
  }
1663
 
1664
  /// Set cancel state.
1665
  void setHasCancel(bool Has) { HasCancel = Has; }
1666
 
1667
public:
1668
  /// Creates directive with a list of \a Clauses.
1669
  ///
1670
  /// \param C AST context.
1671
  /// \param StartLoc Starting location of the directive kind.
1672
  /// \param EndLoc Ending Location of the directive.
1673
  /// \param CollapsedNum Number of collapsed loops.
1674
  /// \param Clauses List of clauses.
1675
  /// \param AssociatedStmt Statement, associated with the directive.
1676
  /// \param Exprs Helper expressions for CodeGen.
1677
  /// \param TaskRedRef Task reduction special reference expression to handle
1678
  /// taskgroup descriptor.
1679
  /// \param HasCancel true if current directive has inner cancel directive.
1680
  ///
1681
  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1682
                                 SourceLocation EndLoc, unsigned CollapsedNum,
1683
                                 ArrayRef<OMPClause *> Clauses,
1684
                                 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1685
                                 Expr *TaskRedRef, bool HasCancel);
1686
 
1687
  /// Creates an empty directive with the place
1688
  /// for \a NumClauses clauses.
1689
  ///
1690
  /// \param C AST context.
1691
  /// \param CollapsedNum Number of collapsed nested loops.
1692
  /// \param NumClauses Number of clauses.
1693
  ///
1694
  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1695
                                      unsigned CollapsedNum, EmptyShell);
1696
 
1697
  /// Returns special task reduction reference expression.
1698
  Expr *getTaskReductionRefExpr() {
1699
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1700
        getLoopsNumber(), llvm::omp::OMPD_for)]);
1701
  }
1702
  const Expr *getTaskReductionRefExpr() const {
1703
    return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1704
  }
1705
 
1706
  /// Return true if current directive has inner cancel directive.
1707
  bool hasCancel() const { return HasCancel; }
1708
 
1709
  static bool classof(const Stmt *T) {
1710
    return T->getStmtClass() == OMPForDirectiveClass;
1711
  }
1712
};
1713
 
1714
/// This represents '#pragma omp for simd' directive.
1715
///
1716
/// \code
1717
/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1718
/// \endcode
1719
/// In this example directive '#pragma omp for simd' has clauses 'private'
1720
/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1721
/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1722
///
1723
class OMPForSimdDirective : public OMPLoopDirective {
1724
  friend class ASTStmtReader;
1725
  friend class OMPExecutableDirective;
1726
  /// Build directive with the given start and end location.
1727
  ///
1728
  /// \param StartLoc Starting location of the directive kind.
1729
  /// \param EndLoc Ending location of the directive.
1730
  /// \param CollapsedNum Number of collapsed nested loops.
1731
  ///
1732
  OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1733
                      unsigned CollapsedNum)
1734
      : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1735
                         StartLoc, EndLoc, CollapsedNum) {}
1736
 
1737
  /// Build an empty directive.
1738
  ///
1739
  /// \param CollapsedNum Number of collapsed nested loops.
1740
  ///
1741
  explicit OMPForSimdDirective(unsigned CollapsedNum)
1742
      : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1743
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
1744
 
1745
public:
1746
  /// Creates directive with a list of \a Clauses.
1747
  ///
1748
  /// \param C AST context.
1749
  /// \param StartLoc Starting location of the directive kind.
1750
  /// \param EndLoc Ending Location of the directive.
1751
  /// \param CollapsedNum Number of collapsed loops.
1752
  /// \param Clauses List of clauses.
1753
  /// \param AssociatedStmt Statement, associated with the directive.
1754
  /// \param Exprs Helper expressions for CodeGen.
1755
  ///
1756
  static OMPForSimdDirective *
1757
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1758
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1759
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
1760
 
1761
  /// Creates an empty directive with the place
1762
  /// for \a NumClauses clauses.
1763
  ///
1764
  /// \param C AST context.
1765
  /// \param CollapsedNum Number of collapsed nested loops.
1766
  /// \param NumClauses Number of clauses.
1767
  ///
1768
  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1769
                                          unsigned NumClauses,
1770
                                          unsigned CollapsedNum, EmptyShell);
1771
 
1772
  static bool classof(const Stmt *T) {
1773
    return T->getStmtClass() == OMPForSimdDirectiveClass;
1774
  }
1775
};
1776
 
1777
/// This represents '#pragma omp sections' directive.
1778
///
1779
/// \code
1780
/// #pragma omp sections private(a,b) reduction(+:c,d)
1781
/// \endcode
1782
/// In this example directive '#pragma omp sections' has clauses 'private' with
1783
/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1784
/// 'c' and 'd'.
1785
///
1786
class OMPSectionsDirective : public OMPExecutableDirective {
1787
  friend class ASTStmtReader;
1788
  friend class OMPExecutableDirective;
1789
 
1790
  /// true if current directive has inner cancel directive.
1791
  bool HasCancel = false;
1792
 
1793
  /// Build directive with the given start and end location.
1794
  ///
1795
  /// \param StartLoc Starting location of the directive kind.
1796
  /// \param EndLoc Ending location of the directive.
1797
  ///
1798
  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1799
      : OMPExecutableDirective(OMPSectionsDirectiveClass,
1800
                               llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1801
 
1802
  /// Build an empty directive.
1803
  ///
1804
  explicit OMPSectionsDirective()
1805
      : OMPExecutableDirective(OMPSectionsDirectiveClass,
1806
                               llvm::omp::OMPD_sections, SourceLocation(),
1807
                               SourceLocation()) {}
1808
 
1809
  /// Sets special task reduction descriptor.
1810
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1811
 
1812
  /// Set cancel state.
1813
  void setHasCancel(bool Has) { HasCancel = Has; }
1814
 
1815
public:
1816
  /// Creates directive with a list of \a Clauses.
1817
  ///
1818
  /// \param C AST context.
1819
  /// \param StartLoc Starting location of the directive kind.
1820
  /// \param EndLoc Ending Location of the directive.
1821
  /// \param Clauses List of clauses.
1822
  /// \param AssociatedStmt Statement, associated with the directive.
1823
  /// \param TaskRedRef Task reduction special reference expression to handle
1824
  /// taskgroup descriptor.
1825
  /// \param HasCancel true if current directive has inner directive.
1826
  ///
1827
  static OMPSectionsDirective *
1828
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1829
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1830
         bool HasCancel);
1831
 
1832
  /// Creates an empty directive with the place for \a NumClauses
1833
  /// clauses.
1834
  ///
1835
  /// \param C AST context.
1836
  /// \param NumClauses Number of clauses.
1837
  ///
1838
  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1839
                                           unsigned NumClauses, EmptyShell);
1840
 
1841
  /// Returns special task reduction reference expression.
1842
  Expr *getTaskReductionRefExpr() {
1843
    return cast_or_null<Expr>(Data->getChildren()[0]);
1844
  }
1845
  const Expr *getTaskReductionRefExpr() const {
1846
    return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1847
  }
1848
 
1849
  /// Return true if current directive has inner cancel directive.
1850
  bool hasCancel() const { return HasCancel; }
1851
 
1852
  static bool classof(const Stmt *T) {
1853
    return T->getStmtClass() == OMPSectionsDirectiveClass;
1854
  }
1855
};
1856
 
1857
/// This represents '#pragma omp section' directive.
1858
///
1859
/// \code
1860
/// #pragma omp section
1861
/// \endcode
1862
///
1863
class OMPSectionDirective : public OMPExecutableDirective {
1864
  friend class ASTStmtReader;
1865
  friend class OMPExecutableDirective;
1866
 
1867
  /// true if current directive has inner cancel directive.
1868
  bool HasCancel = false;
1869
 
1870
  /// Build directive with the given start and end location.
1871
  ///
1872
  /// \param StartLoc Starting location of the directive kind.
1873
  /// \param EndLoc Ending location of the directive.
1874
  ///
1875
  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1876
      : OMPExecutableDirective(OMPSectionDirectiveClass,
1877
                               llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1878
 
1879
  /// Build an empty directive.
1880
  ///
1881
  explicit OMPSectionDirective()
1882
      : OMPExecutableDirective(OMPSectionDirectiveClass,
1883
                               llvm::omp::OMPD_section, SourceLocation(),
1884
                               SourceLocation()) {}
1885
 
1886
public:
1887
  /// Creates directive.
1888
  ///
1889
  /// \param C AST context.
1890
  /// \param StartLoc Starting location of the directive kind.
1891
  /// \param EndLoc Ending Location of the directive.
1892
  /// \param AssociatedStmt Statement, associated with the directive.
1893
  /// \param HasCancel true if current directive has inner directive.
1894
  ///
1895
  static OMPSectionDirective *Create(const ASTContext &C,
1896
                                     SourceLocation StartLoc,
1897
                                     SourceLocation EndLoc,
1898
                                     Stmt *AssociatedStmt, bool HasCancel);
1899
 
1900
  /// Creates an empty directive.
1901
  ///
1902
  /// \param C AST context.
1903
  ///
1904
  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1905
 
1906
  /// Set cancel state.
1907
  void setHasCancel(bool Has) { HasCancel = Has; }
1908
 
1909
  /// Return true if current directive has inner cancel directive.
1910
  bool hasCancel() const { return HasCancel; }
1911
 
1912
  static bool classof(const Stmt *T) {
1913
    return T->getStmtClass() == OMPSectionDirectiveClass;
1914
  }
1915
};
1916
 
1917
/// This represents '#pragma omp single' directive.
1918
///
1919
/// \code
1920
/// #pragma omp single private(a,b) copyprivate(c,d)
1921
/// \endcode
1922
/// In this example directive '#pragma omp single' has clauses 'private' with
1923
/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1924
///
1925
class OMPSingleDirective : public OMPExecutableDirective {
1926
  friend class ASTStmtReader;
1927
  friend class OMPExecutableDirective;
1928
  /// Build directive with the given start and end location.
1929
  ///
1930
  /// \param StartLoc Starting location of the directive kind.
1931
  /// \param EndLoc Ending location of the directive.
1932
  ///
1933
  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1934
      : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1935
                               StartLoc, EndLoc) {}
1936
 
1937
  /// Build an empty directive.
1938
  ///
1939
  explicit OMPSingleDirective()
1940
      : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1941
                               SourceLocation(), SourceLocation()) {}
1942
 
1943
public:
1944
  /// Creates directive with a list of \a Clauses.
1945
  ///
1946
  /// \param C AST context.
1947
  /// \param StartLoc Starting location of the directive kind.
1948
  /// \param EndLoc Ending Location of the directive.
1949
  /// \param Clauses List of clauses.
1950
  /// \param AssociatedStmt Statement, associated with the directive.
1951
  ///
1952
  static OMPSingleDirective *
1953
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1954
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1955
 
1956
  /// Creates an empty directive with the place for \a NumClauses
1957
  /// clauses.
1958
  ///
1959
  /// \param C AST context.
1960
  /// \param NumClauses Number of clauses.
1961
  ///
1962
  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1963
                                         unsigned NumClauses, EmptyShell);
1964
 
1965
  static bool classof(const Stmt *T) {
1966
    return T->getStmtClass() == OMPSingleDirectiveClass;
1967
  }
1968
};
1969
 
1970
/// This represents '#pragma omp master' directive.
1971
///
1972
/// \code
1973
/// #pragma omp master
1974
/// \endcode
1975
///
1976
class OMPMasterDirective : public OMPExecutableDirective {
1977
  friend class ASTStmtReader;
1978
  friend class OMPExecutableDirective;
1979
  /// Build directive with the given start and end location.
1980
  ///
1981
  /// \param StartLoc Starting location of the directive kind.
1982
  /// \param EndLoc Ending location of the directive.
1983
  ///
1984
  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1985
      : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1986
                               StartLoc, EndLoc) {}
1987
 
1988
  /// Build an empty directive.
1989
  ///
1990
  explicit OMPMasterDirective()
1991
      : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1992
                               SourceLocation(), SourceLocation()) {}
1993
 
1994
public:
1995
  /// Creates directive.
1996
  ///
1997
  /// \param C AST context.
1998
  /// \param StartLoc Starting location of the directive kind.
1999
  /// \param EndLoc Ending Location of the directive.
2000
  /// \param AssociatedStmt Statement, associated with the directive.
2001
  ///
2002
  static OMPMasterDirective *Create(const ASTContext &C,
2003
                                    SourceLocation StartLoc,
2004
                                    SourceLocation EndLoc,
2005
                                    Stmt *AssociatedStmt);
2006
 
2007
  /// Creates an empty directive.
2008
  ///
2009
  /// \param C AST context.
2010
  ///
2011
  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2012
 
2013
  static bool classof(const Stmt *T) {
2014
    return T->getStmtClass() == OMPMasterDirectiveClass;
2015
  }
2016
};
2017
 
2018
/// This represents '#pragma omp critical' directive.
2019
///
2020
/// \code
2021
/// #pragma omp critical
2022
/// \endcode
2023
///
2024
class OMPCriticalDirective : public OMPExecutableDirective {
2025
  friend class ASTStmtReader;
2026
  friend class OMPExecutableDirective;
2027
  /// Name of the directive.
2028
  DeclarationNameInfo DirName;
2029
  /// Build directive with the given start and end location.
2030
  ///
2031
  /// \param Name Name of the directive.
2032
  /// \param StartLoc Starting location of the directive kind.
2033
  /// \param EndLoc Ending location of the directive.
2034
  ///
2035
  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
2036
                       SourceLocation EndLoc)
2037
      : OMPExecutableDirective(OMPCriticalDirectiveClass,
2038
                               llvm::omp::OMPD_critical, StartLoc, EndLoc),
2039
        DirName(Name) {}
2040
 
2041
  /// Build an empty directive.
2042
  ///
2043
  explicit OMPCriticalDirective()
2044
      : OMPExecutableDirective(OMPCriticalDirectiveClass,
2045
                               llvm::omp::OMPD_critical, SourceLocation(),
2046
                               SourceLocation()) {}
2047
 
2048
  /// Set name of the directive.
2049
  ///
2050
  /// \param Name Name of the directive.
2051
  ///
2052
  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2053
 
2054
public:
2055
  /// Creates directive.
2056
  ///
2057
  /// \param C AST context.
2058
  /// \param Name Name of the directive.
2059
  /// \param StartLoc Starting location of the directive kind.
2060
  /// \param EndLoc Ending Location of the directive.
2061
  /// \param Clauses List of clauses.
2062
  /// \param AssociatedStmt Statement, associated with the directive.
2063
  ///
2064
  static OMPCriticalDirective *
2065
  Create(const ASTContext &C, const DeclarationNameInfo &Name,
2066
         SourceLocation StartLoc, SourceLocation EndLoc,
2067
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2068
 
2069
  /// Creates an empty directive.
2070
  ///
2071
  /// \param C AST context.
2072
  /// \param NumClauses Number of clauses.
2073
  ///
2074
  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2075
                                           unsigned NumClauses, EmptyShell);
2076
 
2077
  /// Return name of the directive.
2078
  ///
2079
  DeclarationNameInfo getDirectiveName() const { return DirName; }
2080
 
2081
  static bool classof(const Stmt *T) {
2082
    return T->getStmtClass() == OMPCriticalDirectiveClass;
2083
  }
2084
};
2085
 
2086
/// This represents '#pragma omp parallel for' directive.
2087
///
2088
/// \code
2089
/// #pragma omp parallel for private(a,b) reduction(+:c,d)
2090
/// \endcode
2091
/// In this example directive '#pragma omp parallel for' has clauses 'private'
2092
/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2093
/// variables 'c' and 'd'.
2094
///
2095
class OMPParallelForDirective : public OMPLoopDirective {
2096
  friend class ASTStmtReader;
2097
  friend class OMPExecutableDirective;
2098
 
2099
  /// true if current region has inner cancel directive.
2100
  bool HasCancel = false;
2101
 
2102
  /// Build directive with the given start and end location.
2103
  ///
2104
  /// \param StartLoc Starting location of the directive kind.
2105
  /// \param EndLoc Ending location of the directive.
2106
  /// \param CollapsedNum Number of collapsed nested loops.
2107
  ///
2108
  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2109
                          unsigned CollapsedNum)
2110
      : OMPLoopDirective(OMPParallelForDirectiveClass,
2111
                         llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2112
                         CollapsedNum) {}
2113
 
2114
  /// Build an empty directive.
2115
  ///
2116
  /// \param CollapsedNum Number of collapsed nested loops.
2117
  ///
2118
  explicit OMPParallelForDirective(unsigned CollapsedNum)
2119
      : OMPLoopDirective(OMPParallelForDirectiveClass,
2120
                         llvm::omp::OMPD_parallel_for, SourceLocation(),
2121
                         SourceLocation(), CollapsedNum) {}
2122
 
2123
  /// Sets special task reduction descriptor.
2124
  void setTaskReductionRefExpr(Expr *E) {
2125
    Data->getChildren()[numLoopChildren(getLoopsNumber(),
2126
                                        llvm::omp::OMPD_parallel_for)] = E;
2127
  }
2128
 
2129
  /// Set cancel state.
2130
  void setHasCancel(bool Has) { HasCancel = Has; }
2131
 
2132
public:
2133
  /// Creates directive with a list of \a Clauses.
2134
  ///
2135
  /// \param C AST context.
2136
  /// \param StartLoc Starting location of the directive kind.
2137
  /// \param EndLoc Ending Location of the directive.
2138
  /// \param CollapsedNum Number of collapsed loops.
2139
  /// \param Clauses List of clauses.
2140
  /// \param AssociatedStmt Statement, associated with the directive.
2141
  /// \param Exprs Helper expressions for CodeGen.
2142
  /// \param TaskRedRef Task reduction special reference expression to handle
2143
  /// taskgroup descriptor.
2144
  /// \param HasCancel true if current directive has inner cancel directive.
2145
  ///
2146
  static OMPParallelForDirective *
2147
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2148
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2149
         Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2150
         bool HasCancel);
2151
 
2152
  /// Creates an empty directive with the place
2153
  /// for \a NumClauses clauses.
2154
  ///
2155
  /// \param C AST context.
2156
  /// \param CollapsedNum Number of collapsed nested loops.
2157
  /// \param NumClauses Number of clauses.
2158
  ///
2159
  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2160
                                              unsigned NumClauses,
2161
                                              unsigned CollapsedNum,
2162
                                              EmptyShell);
2163
 
2164
  /// Returns special task reduction reference expression.
2165
  Expr *getTaskReductionRefExpr() {
2166
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2167
        getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2168
  }
2169
  const Expr *getTaskReductionRefExpr() const {
2170
    return const_cast<OMPParallelForDirective *>(this)
2171
        ->getTaskReductionRefExpr();
2172
  }
2173
 
2174
  /// Return true if current directive has inner cancel directive.
2175
  bool hasCancel() const { return HasCancel; }
2176
 
2177
  static bool classof(const Stmt *T) {
2178
    return T->getStmtClass() == OMPParallelForDirectiveClass;
2179
  }
2180
};
2181
 
2182
/// This represents '#pragma omp parallel for simd' directive.
2183
///
2184
/// \code
2185
/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2186
/// \endcode
2187
/// In this example directive '#pragma omp parallel for simd' has clauses
2188
/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2189
/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2190
/// 'd'.
2191
///
2192
class OMPParallelForSimdDirective : public OMPLoopDirective {
2193
  friend class ASTStmtReader;
2194
  friend class OMPExecutableDirective;
2195
  /// Build directive with the given start and end location.
2196
  ///
2197
  /// \param StartLoc Starting location of the directive kind.
2198
  /// \param EndLoc Ending location of the directive.
2199
  /// \param CollapsedNum Number of collapsed nested loops.
2200
  ///
2201
  OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2202
                              unsigned CollapsedNum)
2203
      : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2204
                         llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2205
                         CollapsedNum) {}
2206
 
2207
  /// Build an empty directive.
2208
  ///
2209
  /// \param CollapsedNum Number of collapsed nested loops.
2210
  ///
2211
  explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2212
      : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2213
                         llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2214
                         SourceLocation(), CollapsedNum) {}
2215
 
2216
public:
2217
  /// Creates directive with a list of \a Clauses.
2218
  ///
2219
  /// \param C AST context.
2220
  /// \param StartLoc Starting location of the directive kind.
2221
  /// \param EndLoc Ending Location of the directive.
2222
  /// \param CollapsedNum Number of collapsed loops.
2223
  /// \param Clauses List of clauses.
2224
  /// \param AssociatedStmt Statement, associated with the directive.
2225
  /// \param Exprs Helper expressions for CodeGen.
2226
  ///
2227
  static OMPParallelForSimdDirective *
2228
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2229
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2230
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2231
 
2232
  /// Creates an empty directive with the place
2233
  /// for \a NumClauses clauses.
2234
  ///
2235
  /// \param C AST context.
2236
  /// \param CollapsedNum Number of collapsed nested loops.
2237
  /// \param NumClauses Number of clauses.
2238
  ///
2239
  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2240
                                                  unsigned NumClauses,
2241
                                                  unsigned CollapsedNum,
2242
                                                  EmptyShell);
2243
 
2244
  static bool classof(const Stmt *T) {
2245
    return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2246
  }
2247
};
2248
 
2249
/// This represents '#pragma omp parallel master' directive.
2250
///
2251
/// \code
2252
/// #pragma omp parallel master private(a,b)
2253
/// \endcode
2254
/// In this example directive '#pragma omp parallel master' has clauses
2255
/// 'private' with the variables 'a' and 'b'
2256
///
2257
class OMPParallelMasterDirective : public OMPExecutableDirective {
2258
  friend class ASTStmtReader;
2259
  friend class OMPExecutableDirective;
2260
 
2261
  OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2262
      : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2263
                               llvm::omp::OMPD_parallel_master, StartLoc,
2264
                               EndLoc) {}
2265
 
2266
  explicit OMPParallelMasterDirective()
2267
      : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2268
                               llvm::omp::OMPD_parallel_master,
2269
                               SourceLocation(), SourceLocation()) {}
2270
 
2271
  /// Sets special task reduction descriptor.
2272
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2273
 
2274
public:
2275
  /// Creates directive with a list of \a Clauses.
2276
  ///
2277
  /// \param C AST context.
2278
  /// \param StartLoc Starting location of the directive kind.
2279
  /// \param EndLoc Ending Location of the directive.
2280
  /// \param Clauses List of clauses.
2281
  /// \param AssociatedStmt Statement, associated with the directive.
2282
  /// \param TaskRedRef Task reduction special reference expression to handle
2283
  /// taskgroup descriptor.
2284
  ///
2285
  static OMPParallelMasterDirective *
2286
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2287
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2288
 
2289
  /// Creates an empty directive with the place for \a NumClauses
2290
  /// clauses.
2291
  ///
2292
  /// \param C AST context.
2293
  /// \param NumClauses Number of clauses.
2294
  ///
2295
  static OMPParallelMasterDirective *
2296
  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2297
 
2298
  /// Returns special task reduction reference expression.
2299
  Expr *getTaskReductionRefExpr() {
2300
    return cast_or_null<Expr>(Data->getChildren()[0]);
2301
  }
2302
  const Expr *getTaskReductionRefExpr() const {
2303
    return const_cast<OMPParallelMasterDirective *>(this)
2304
        ->getTaskReductionRefExpr();
2305
  }
2306
 
2307
  static bool classof(const Stmt *T) {
2308
    return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2309
  }
2310
};
2311
 
2312
/// This represents '#pragma omp parallel masked' directive.
2313
///
2314
/// \code
2315
/// #pragma omp parallel masked filter(tid)
2316
/// \endcode
2317
/// In this example directive '#pragma omp parallel masked' has a clause
2318
/// 'filter' with the variable tid
2319
///
2320
class OMPParallelMaskedDirective final : public OMPExecutableDirective {
2321
  friend class ASTStmtReader;
2322
  friend class OMPExecutableDirective;
2323
 
2324
  OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2325
      : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2326
                               llvm::omp::OMPD_parallel_masked, StartLoc,
2327
                               EndLoc) {}
2328
 
2329
  explicit OMPParallelMaskedDirective()
2330
      : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2331
                               llvm::omp::OMPD_parallel_masked,
2332
                               SourceLocation(), SourceLocation()) {}
2333
 
2334
  /// Sets special task reduction descriptor.
2335
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2336
 
2337
public:
2338
  /// Creates directive with a list of \a Clauses.
2339
  ///
2340
  /// \param C AST context.
2341
  /// \param StartLoc Starting location of the directive kind.
2342
  /// \param EndLoc Ending Location of the directive.
2343
  /// \param Clauses List of clauses.
2344
  /// \param AssociatedStmt Statement, associated with the directive.
2345
  /// \param TaskRedRef Task reduction special reference expression to handle
2346
  /// taskgroup descriptor.
2347
  ///
2348
  static OMPParallelMaskedDirective *
2349
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2350
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2351
 
2352
  /// Creates an empty directive with the place for \a NumClauses
2353
  /// clauses.
2354
  ///
2355
  /// \param C AST context.
2356
  /// \param NumClauses Number of clauses.
2357
  ///
2358
  static OMPParallelMaskedDirective *
2359
  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2360
 
2361
  /// Returns special task reduction reference expression.
2362
  Expr *getTaskReductionRefExpr() {
2363
    return cast_or_null<Expr>(Data->getChildren()[0]);
2364
  }
2365
  const Expr *getTaskReductionRefExpr() const {
2366
    return const_cast<OMPParallelMaskedDirective *>(this)
2367
        ->getTaskReductionRefExpr();
2368
  }
2369
 
2370
  static bool classof(const Stmt *T) {
2371
    return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2372
  }
2373
};
2374
 
2375
/// This represents '#pragma omp parallel sections' directive.
2376
///
2377
/// \code
2378
/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2379
/// \endcode
2380
/// In this example directive '#pragma omp parallel sections' has clauses
2381
/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2382
/// and variables 'c' and 'd'.
2383
///
2384
class OMPParallelSectionsDirective : public OMPExecutableDirective {
2385
  friend class ASTStmtReader;
2386
  friend class OMPExecutableDirective;
2387
 
2388
  /// true if current directive has inner cancel directive.
2389
  bool HasCancel = false;
2390
 
2391
  /// Build directive with the given start and end location.
2392
  ///
2393
  /// \param StartLoc Starting location of the directive kind.
2394
  /// \param EndLoc Ending location of the directive.
2395
  ///
2396
  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2397
      : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2398
                               llvm::omp::OMPD_parallel_sections, StartLoc,
2399
                               EndLoc) {}
2400
 
2401
  /// Build an empty directive.
2402
  ///
2403
  explicit OMPParallelSectionsDirective()
2404
      : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2405
                               llvm::omp::OMPD_parallel_sections,
2406
                               SourceLocation(), SourceLocation()) {}
2407
 
2408
  /// Sets special task reduction descriptor.
2409
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2410
 
2411
  /// Set cancel state.
2412
  void setHasCancel(bool Has) { HasCancel = Has; }
2413
 
2414
public:
2415
  /// Creates directive with a list of \a Clauses.
2416
  ///
2417
  /// \param C AST context.
2418
  /// \param StartLoc Starting location of the directive kind.
2419
  /// \param EndLoc Ending Location of the directive.
2420
  /// \param Clauses List of clauses.
2421
  /// \param AssociatedStmt Statement, associated with the directive.
2422
  /// \param TaskRedRef Task reduction special reference expression to handle
2423
  /// taskgroup descriptor.
2424
  /// \param HasCancel true if current directive has inner cancel directive.
2425
  ///
2426
  static OMPParallelSectionsDirective *
2427
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2428
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2429
         bool HasCancel);
2430
 
2431
  /// Creates an empty directive with the place for \a NumClauses
2432
  /// clauses.
2433
  ///
2434
  /// \param C AST context.
2435
  /// \param NumClauses Number of clauses.
2436
  ///
2437
  static OMPParallelSectionsDirective *
2438
  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2439
 
2440
  /// Returns special task reduction reference expression.
2441
  Expr *getTaskReductionRefExpr() {
2442
    return cast_or_null<Expr>(Data->getChildren()[0]);
2443
  }
2444
  const Expr *getTaskReductionRefExpr() const {
2445
    return const_cast<OMPParallelSectionsDirective *>(this)
2446
        ->getTaskReductionRefExpr();
2447
  }
2448
 
2449
  /// Return true if current directive has inner cancel directive.
2450
  bool hasCancel() const { return HasCancel; }
2451
 
2452
  static bool classof(const Stmt *T) {
2453
    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2454
  }
2455
};
2456
 
2457
/// This represents '#pragma omp task' directive.
2458
///
2459
/// \code
2460
/// #pragma omp task private(a,b) final(d)
2461
/// \endcode
2462
/// In this example directive '#pragma omp task' has clauses 'private' with the
2463
/// variables 'a' and 'b' and 'final' with condition 'd'.
2464
///
2465
class OMPTaskDirective : public OMPExecutableDirective {
2466
  friend class ASTStmtReader;
2467
  friend class OMPExecutableDirective;
2468
  /// true if this directive has inner cancel directive.
2469
  bool HasCancel = false;
2470
 
2471
  /// Build directive with the given start and end location.
2472
  ///
2473
  /// \param StartLoc Starting location of the directive kind.
2474
  /// \param EndLoc Ending location of the directive.
2475
  ///
2476
  OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2477
      : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2478
                               StartLoc, EndLoc) {}
2479
 
2480
  /// Build an empty directive.
2481
  ///
2482
  explicit OMPTaskDirective()
2483
      : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2484
                               SourceLocation(), SourceLocation()) {}
2485
 
2486
  /// Set cancel state.
2487
  void setHasCancel(bool Has) { HasCancel = Has; }
2488
 
2489
public:
2490
  /// Creates directive with a list of \a Clauses.
2491
  ///
2492
  /// \param C AST context.
2493
  /// \param StartLoc Starting location of the directive kind.
2494
  /// \param EndLoc Ending Location of the directive.
2495
  /// \param Clauses List of clauses.
2496
  /// \param AssociatedStmt Statement, associated with the directive.
2497
  /// \param HasCancel true, if current directive has inner cancel directive.
2498
  ///
2499
  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2500
                                  SourceLocation EndLoc,
2501
                                  ArrayRef<OMPClause *> Clauses,
2502
                                  Stmt *AssociatedStmt, bool HasCancel);
2503
 
2504
  /// Creates an empty directive with the place for \a NumClauses
2505
  /// clauses.
2506
  ///
2507
  /// \param C AST context.
2508
  /// \param NumClauses Number of clauses.
2509
  ///
2510
  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2511
                                       EmptyShell);
2512
 
2513
  /// Return true if current directive has inner cancel directive.
2514
  bool hasCancel() const { return HasCancel; }
2515
 
2516
  static bool classof(const Stmt *T) {
2517
    return T->getStmtClass() == OMPTaskDirectiveClass;
2518
  }
2519
};
2520
 
2521
/// This represents '#pragma omp taskyield' directive.
2522
///
2523
/// \code
2524
/// #pragma omp taskyield
2525
/// \endcode
2526
///
2527
class OMPTaskyieldDirective : public OMPExecutableDirective {
2528
  friend class ASTStmtReader;
2529
  friend class OMPExecutableDirective;
2530
  /// Build directive with the given start and end location.
2531
  ///
2532
  /// \param StartLoc Starting location of the directive kind.
2533
  /// \param EndLoc Ending location of the directive.
2534
  ///
2535
  OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2536
      : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2537
                               llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2538
 
2539
  /// Build an empty directive.
2540
  ///
2541
  explicit OMPTaskyieldDirective()
2542
      : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2543
                               llvm::omp::OMPD_taskyield, SourceLocation(),
2544
                               SourceLocation()) {}
2545
 
2546
public:
2547
  /// Creates directive.
2548
  ///
2549
  /// \param C AST context.
2550
  /// \param StartLoc Starting location of the directive kind.
2551
  /// \param EndLoc Ending Location of the directive.
2552
  ///
2553
  static OMPTaskyieldDirective *
2554
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2555
 
2556
  /// Creates an empty directive.
2557
  ///
2558
  /// \param C AST context.
2559
  ///
2560
  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2561
 
2562
  static bool classof(const Stmt *T) {
2563
    return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2564
  }
2565
};
2566
 
2567
/// This represents '#pragma omp barrier' directive.
2568
///
2569
/// \code
2570
/// #pragma omp barrier
2571
/// \endcode
2572
///
2573
class OMPBarrierDirective : public OMPExecutableDirective {
2574
  friend class ASTStmtReader;
2575
  friend class OMPExecutableDirective;
2576
  /// Build directive with the given start and end location.
2577
  ///
2578
  /// \param StartLoc Starting location of the directive kind.
2579
  /// \param EndLoc Ending location of the directive.
2580
  ///
2581
  OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2582
      : OMPExecutableDirective(OMPBarrierDirectiveClass,
2583
                               llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2584
 
2585
  /// Build an empty directive.
2586
  ///
2587
  explicit OMPBarrierDirective()
2588
      : OMPExecutableDirective(OMPBarrierDirectiveClass,
2589
                               llvm::omp::OMPD_barrier, SourceLocation(),
2590
                               SourceLocation()) {}
2591
 
2592
public:
2593
  /// Creates directive.
2594
  ///
2595
  /// \param C AST context.
2596
  /// \param StartLoc Starting location of the directive kind.
2597
  /// \param EndLoc Ending Location of the directive.
2598
  ///
2599
  static OMPBarrierDirective *
2600
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2601
 
2602
  /// Creates an empty directive.
2603
  ///
2604
  /// \param C AST context.
2605
  ///
2606
  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2607
 
2608
  static bool classof(const Stmt *T) {
2609
    return T->getStmtClass() == OMPBarrierDirectiveClass;
2610
  }
2611
};
2612
 
2613
/// This represents '#pragma omp taskwait' directive.
2614
///
2615
/// \code
2616
/// #pragma omp taskwait
2617
/// \endcode
2618
///
2619
class OMPTaskwaitDirective : public OMPExecutableDirective {
2620
  friend class ASTStmtReader;
2621
  friend class OMPExecutableDirective;
2622
  /// Build directive with the given start and end location.
2623
  ///
2624
  /// \param StartLoc Starting location of the directive kind.
2625
  /// \param EndLoc Ending location of the directive.
2626
  ///
2627
  OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2628
      : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2629
                               llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2630
 
2631
  /// Build an empty directive.
2632
  ///
2633
  explicit OMPTaskwaitDirective()
2634
      : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2635
                               llvm::omp::OMPD_taskwait, SourceLocation(),
2636
                               SourceLocation()) {}
2637
 
2638
public:
2639
  /// Creates directive.
2640
  ///
2641
  /// \param C AST context.
2642
  /// \param StartLoc Starting location of the directive kind.
2643
  /// \param EndLoc Ending Location of the directive.
2644
  /// \param Clauses List of clauses.
2645
  ///
2646
  static OMPTaskwaitDirective *Create(const ASTContext &C,
2647
                                      SourceLocation StartLoc,
2648
                                      SourceLocation EndLoc,
2649
                                      ArrayRef<OMPClause *> Clauses);
2650
 
2651
  /// Creates an empty directive.
2652
  ///
2653
  /// \param C AST context.
2654
  /// \param NumClauses Number of clauses.
2655
  ///
2656
  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2657
                                           unsigned NumClauses, EmptyShell);
2658
 
2659
  static bool classof(const Stmt *T) {
2660
    return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2661
  }
2662
};
2663
 
2664
/// This represents '#pragma omp taskgroup' directive.
2665
///
2666
/// \code
2667
/// #pragma omp taskgroup
2668
/// \endcode
2669
///
2670
class OMPTaskgroupDirective : public OMPExecutableDirective {
2671
  friend class ASTStmtReader;
2672
  friend class OMPExecutableDirective;
2673
  /// Build directive with the given start and end location.
2674
  ///
2675
  /// \param StartLoc Starting location of the directive kind.
2676
  /// \param EndLoc Ending location of the directive.
2677
  ///
2678
  OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2679
      : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2680
                               llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2681
 
2682
  /// Build an empty directive.
2683
  ///
2684
  explicit OMPTaskgroupDirective()
2685
      : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2686
                               llvm::omp::OMPD_taskgroup, SourceLocation(),
2687
                               SourceLocation()) {}
2688
 
2689
  /// Sets the task_reduction return variable.
2690
  void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2691
 
2692
public:
2693
  /// Creates directive.
2694
  ///
2695
  /// \param C AST context.
2696
  /// \param StartLoc Starting location of the directive kind.
2697
  /// \param EndLoc Ending Location of the directive.
2698
  /// \param Clauses List of clauses.
2699
  /// \param AssociatedStmt Statement, associated with the directive.
2700
  /// \param ReductionRef Reference to the task_reduction return variable.
2701
  ///
2702
  static OMPTaskgroupDirective *
2703
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2704
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2705
         Expr *ReductionRef);
2706
 
2707
  /// Creates an empty directive.
2708
  ///
2709
  /// \param C AST context.
2710
  /// \param NumClauses Number of clauses.
2711
  ///
2712
  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2713
                                            unsigned NumClauses, EmptyShell);
2714
 
2715
 
2716
  /// Returns reference to the task_reduction return variable.
2717
  const Expr *getReductionRef() const {
2718
    return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2719
  }
2720
  Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2721
 
2722
  static bool classof(const Stmt *T) {
2723
    return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2724
  }
2725
};
2726
 
2727
/// This represents '#pragma omp flush' directive.
2728
///
2729
/// \code
2730
/// #pragma omp flush(a,b)
2731
/// \endcode
2732
/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2733
/// and 'b'.
2734
/// 'omp flush' directive does not have clauses but have an optional list of
2735
/// variables to flush. This list of variables is stored within some fake clause
2736
/// FlushClause.
2737
class OMPFlushDirective : public OMPExecutableDirective {
2738
  friend class ASTStmtReader;
2739
  friend class OMPExecutableDirective;
2740
  /// Build directive with the given start and end location.
2741
  ///
2742
  /// \param StartLoc Starting location of the directive kind.
2743
  /// \param EndLoc Ending location of the directive.
2744
  ///
2745
  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2746
      : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2747
                               StartLoc, EndLoc) {}
2748
 
2749
  /// Build an empty directive.
2750
  ///
2751
  explicit OMPFlushDirective()
2752
      : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2753
                               SourceLocation(), SourceLocation()) {}
2754
 
2755
public:
2756
  /// Creates directive with a list of \a Clauses.
2757
  ///
2758
  /// \param C AST context.
2759
  /// \param StartLoc Starting location of the directive kind.
2760
  /// \param EndLoc Ending Location of the directive.
2761
  /// \param Clauses List of clauses (only single OMPFlushClause clause is
2762
  /// allowed).
2763
  ///
2764
  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2765
                                   SourceLocation EndLoc,
2766
                                   ArrayRef<OMPClause *> Clauses);
2767
 
2768
  /// Creates an empty directive with the place for \a NumClauses
2769
  /// clauses.
2770
  ///
2771
  /// \param C AST context.
2772
  /// \param NumClauses Number of clauses.
2773
  ///
2774
  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2775
                                        unsigned NumClauses, EmptyShell);
2776
 
2777
  static bool classof(const Stmt *T) {
2778
    return T->getStmtClass() == OMPFlushDirectiveClass;
2779
  }
2780
};
2781
 
2782
/// This represents '#pragma omp depobj' directive.
2783
///
2784
/// \code
2785
/// #pragma omp depobj(a) depend(in:x,y)
2786
/// \endcode
2787
/// In this example directive '#pragma omp  depobj' initializes a depobj object
2788
/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2789
class OMPDepobjDirective final : public OMPExecutableDirective {
2790
  friend class ASTStmtReader;
2791
  friend class OMPExecutableDirective;
2792
 
2793
  /// Build directive with the given start and end location.
2794
  ///
2795
  /// \param StartLoc Starting location of the directive kind.
2796
  /// \param EndLoc Ending location of the directive.
2797
  ///
2798
  OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2799
      : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2800
                               StartLoc, EndLoc) {}
2801
 
2802
  /// Build an empty directive.
2803
  ///
2804
  explicit OMPDepobjDirective()
2805
      : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2806
                               SourceLocation(), SourceLocation()) {}
2807
 
2808
public:
2809
  /// Creates directive with a list of \a Clauses.
2810
  ///
2811
  /// \param C AST context.
2812
  /// \param StartLoc Starting location of the directive kind.
2813
  /// \param EndLoc Ending Location of the directive.
2814
  /// \param Clauses List of clauses.
2815
  ///
2816
  static OMPDepobjDirective *Create(const ASTContext &C,
2817
                                    SourceLocation StartLoc,
2818
                                    SourceLocation EndLoc,
2819
                                    ArrayRef<OMPClause *> Clauses);
2820
 
2821
  /// Creates an empty directive with the place for \a NumClauses
2822
  /// clauses.
2823
  ///
2824
  /// \param C AST context.
2825
  /// \param NumClauses Number of clauses.
2826
  ///
2827
  static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2828
                                         unsigned NumClauses, EmptyShell);
2829
 
2830
  static bool classof(const Stmt *T) {
2831
    return T->getStmtClass() == OMPDepobjDirectiveClass;
2832
  }
2833
};
2834
 
2835
/// This represents '#pragma omp ordered' directive.
2836
///
2837
/// \code
2838
/// #pragma omp ordered
2839
/// \endcode
2840
///
2841
class OMPOrderedDirective : public OMPExecutableDirective {
2842
  friend class ASTStmtReader;
2843
  friend class OMPExecutableDirective;
2844
  /// Build directive with the given start and end location.
2845
  ///
2846
  /// \param StartLoc Starting location of the directive kind.
2847
  /// \param EndLoc Ending location of the directive.
2848
  ///
2849
  OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2850
      : OMPExecutableDirective(OMPOrderedDirectiveClass,
2851
                               llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2852
 
2853
  /// Build an empty directive.
2854
  ///
2855
  explicit OMPOrderedDirective()
2856
      : OMPExecutableDirective(OMPOrderedDirectiveClass,
2857
                               llvm::omp::OMPD_ordered, SourceLocation(),
2858
                               SourceLocation()) {}
2859
 
2860
public:
2861
  /// Creates directive.
2862
  ///
2863
  /// \param C AST context.
2864
  /// \param StartLoc Starting location of the directive kind.
2865
  /// \param EndLoc Ending Location of the directive.
2866
  /// \param Clauses List of clauses.
2867
  /// \param AssociatedStmt Statement, associated with the directive.
2868
  ///
2869
  static OMPOrderedDirective *
2870
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2871
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2872
 
2873
  /// Creates an empty directive.
2874
  ///
2875
  /// \param C AST context.
2876
  /// \param NumClauses Number of clauses.
2877
  /// \param IsStandalone true, if the standalone directive is created.
2878
  ///
2879
  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2880
                                          unsigned NumClauses,
2881
                                          bool IsStandalone, EmptyShell);
2882
 
2883
  static bool classof(const Stmt *T) {
2884
    return T->getStmtClass() == OMPOrderedDirectiveClass;
2885
  }
2886
};
2887
 
2888
/// This represents '#pragma omp atomic' directive.
2889
///
2890
/// \code
2891
/// #pragma omp atomic capture
2892
/// \endcode
2893
/// In this example directive '#pragma omp atomic' has clause 'capture'.
2894
///
2895
class OMPAtomicDirective : public OMPExecutableDirective {
2896
  friend class ASTStmtReader;
2897
  friend class OMPExecutableDirective;
2898
 
2899
  struct FlagTy {
2900
    /// Used for 'atomic update' or 'atomic capture' constructs. They may
2901
    /// have atomic expressions of forms:
2902
    /// \code
2903
    /// x = x binop expr;
2904
    /// x = expr binop x;
2905
    /// \endcode
2906
    /// This field is 1 for the first form of the expression and 0 for the
2907
    /// second. Required for correct codegen of non-associative operations (like
2908
    /// << or >>).
2909
    uint8_t IsXLHSInRHSPart : 1;
2910
    /// Used for 'atomic update' or 'atomic capture' constructs. They may
2911
    /// have atomic expressions of forms:
2912
    /// \code
2913
    /// v = x; <update x>;
2914
    /// <update x>; v = x;
2915
    /// \endcode
2916
    /// This field is 1 for the first(postfix) form of the expression and 0
2917
    /// otherwise.
2918
    uint8_t IsPostfixUpdate : 1;
2919
    /// 1 if 'v' is updated only when the condition is false (compare capture
2920
    /// only).
2921
    uint8_t IsFailOnly : 1;
2922
  } Flags;
2923
 
2924
  /// Build directive with the given start and end location.
2925
  ///
2926
  /// \param StartLoc Starting location of the directive kind.
2927
  /// \param EndLoc Ending location of the directive.
2928
  ///
2929
  OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2930
      : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2931
                               StartLoc, EndLoc) {}
2932
 
2933
  /// Build an empty directive.
2934
  ///
2935
  explicit OMPAtomicDirective()
2936
      : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2937
                               SourceLocation(), SourceLocation()) {}
2938
 
2939
  enum DataPositionTy : size_t {
2940
    POS_X = 0,
2941
    POS_V,
2942
    POS_E,
2943
    POS_UpdateExpr,
2944
    POS_D,
2945
    POS_Cond,
2946
    POS_R,
2947
  };
2948
 
2949
  /// Set 'x' part of the associated expression/statement.
2950
  void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2951
  /// Set helper expression of the form
2952
  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2953
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2954
  void setUpdateExpr(Expr *UE) {
2955
    Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2956
  }
2957
  /// Set 'v' part of the associated expression/statement.
2958
  void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2959
  /// Set 'r' part of the associated expression/statement.
2960
  void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
2961
  /// Set 'expr' part of the associated expression/statement.
2962
  void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2963
  /// Set 'd' part of the associated expression/statement.
2964
  void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2965
  /// Set conditional expression in `atomic compare`.
2966
  void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2967
 
2968
public:
2969
  struct Expressions {
2970
    /// 'x' part of the associated expression/statement.
2971
    Expr *X = nullptr;
2972
    /// 'v' part of the associated expression/statement.
2973
    Expr *V = nullptr;
2974
    // 'r' part of the associated expression/statement.
2975
    Expr *R = nullptr;
2976
    /// 'expr' part of the associated expression/statement.
2977
    Expr *E = nullptr;
2978
    /// UE Helper expression of the form:
2979
    /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2980
    /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2981
    Expr *UE = nullptr;
2982
    /// 'd' part of the associated expression/statement.
2983
    Expr *D = nullptr;
2984
    /// Conditional expression in `atomic compare` construct.
2985
    Expr *Cond = nullptr;
2986
    /// True if UE has the first form and false if the second.
2987
    bool IsXLHSInRHSPart;
2988
    /// True if original value of 'x' must be stored in 'v', not an updated one.
2989
    bool IsPostfixUpdate;
2990
    /// True if 'v' is updated only when the condition is false (compare capture
2991
    /// only).
2992
    bool IsFailOnly;
2993
  };
2994
 
2995
  /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2996
  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2997
  /// detailed description of 'x', 'v' and 'expr').
2998
  ///
2999
  /// \param C AST context.
3000
  /// \param StartLoc Starting location of the directive kind.
3001
  /// \param EndLoc Ending Location of the directive.
3002
  /// \param Clauses List of clauses.
3003
  /// \param AssociatedStmt Statement, associated with the directive.
3004
  /// \param Exprs Associated expressions or statements.
3005
  static OMPAtomicDirective *Create(const ASTContext &C,
3006
                                    SourceLocation StartLoc,
3007
                                    SourceLocation EndLoc,
3008
                                    ArrayRef<OMPClause *> Clauses,
3009
                                    Stmt *AssociatedStmt, Expressions Exprs);
3010
 
3011
  /// Creates an empty directive with the place for \a NumClauses
3012
  /// clauses.
3013
  ///
3014
  /// \param C AST context.
3015
  /// \param NumClauses Number of clauses.
3016
  ///
3017
  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
3018
                                         unsigned NumClauses, EmptyShell);
3019
 
3020
  /// Get 'x' part of the associated expression/statement.
3021
  Expr *getX() {
3022
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3023
  }
3024
  const Expr *getX() const {
3025
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3026
  }
3027
  /// Get helper expression of the form
3028
  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3029
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3030
  Expr *getUpdateExpr() {
3031
    return cast_or_null<Expr>(
3032
        Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3033
  }
3034
  const Expr *getUpdateExpr() const {
3035
    return cast_or_null<Expr>(
3036
        Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3037
  }
3038
  /// Return true if helper update expression has form
3039
  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3040
  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3041
  bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3042
  /// Return true if 'v' expression must be updated to original value of
3043
  /// 'x', false if 'v' must be updated to the new value of 'x'.
3044
  bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3045
  /// Return true if 'v' is updated only when the condition is evaluated false
3046
  /// (compare capture only).
3047
  bool isFailOnly() const { return Flags.IsFailOnly; }
3048
  /// Get 'v' part of the associated expression/statement.
3049
  Expr *getV() {
3050
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3051
  }
3052
  const Expr *getV() const {
3053
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3054
  }
3055
  /// Get 'r' part of the associated expression/statement.
3056
  Expr *getR() {
3057
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3058
  }
3059
  const Expr *getR() const {
3060
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3061
  }
3062
  /// Get 'expr' part of the associated expression/statement.
3063
  Expr *getExpr() {
3064
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3065
  }
3066
  const Expr *getExpr() const {
3067
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3068
  }
3069
  /// Get 'd' part of the associated expression/statement.
3070
  Expr *getD() {
3071
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3072
  }
3073
  Expr *getD() const {
3074
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3075
  }
3076
  /// Get the 'cond' part of the source atomic expression.
3077
  Expr *getCondExpr() {
3078
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3079
  }
3080
  Expr *getCondExpr() const {
3081
    return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3082
  }
3083
 
3084
  static bool classof(const Stmt *T) {
3085
    return T->getStmtClass() == OMPAtomicDirectiveClass;
3086
  }
3087
};
3088
 
3089
/// This represents '#pragma omp target' directive.
3090
///
3091
/// \code
3092
/// #pragma omp target if(a)
3093
/// \endcode
3094
/// In this example directive '#pragma omp target' has clause 'if' with
3095
/// condition 'a'.
3096
///
3097
class OMPTargetDirective : public OMPExecutableDirective {
3098
  friend class ASTStmtReader;
3099
  friend class OMPExecutableDirective;
3100
  /// Build directive with the given start and end location.
3101
  ///
3102
  /// \param StartLoc Starting location of the directive kind.
3103
  /// \param EndLoc Ending location of the directive.
3104
  ///
3105
  OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3106
      : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3107
                               StartLoc, EndLoc) {}
3108
 
3109
  /// Build an empty directive.
3110
  ///
3111
  explicit OMPTargetDirective()
3112
      : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3113
                               SourceLocation(), SourceLocation()) {}
3114
 
3115
public:
3116
  /// Creates directive with a list of \a Clauses.
3117
  ///
3118
  /// \param C AST context.
3119
  /// \param StartLoc Starting location of the directive kind.
3120
  /// \param EndLoc Ending Location of the directive.
3121
  /// \param Clauses List of clauses.
3122
  /// \param AssociatedStmt Statement, associated with the directive.
3123
  ///
3124
  static OMPTargetDirective *
3125
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3126
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3127
 
3128
  /// Creates an empty directive with the place for \a NumClauses
3129
  /// clauses.
3130
  ///
3131
  /// \param C AST context.
3132
  /// \param NumClauses Number of clauses.
3133
  ///
3134
  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3135
                                         unsigned NumClauses, EmptyShell);
3136
 
3137
  static bool classof(const Stmt *T) {
3138
    return T->getStmtClass() == OMPTargetDirectiveClass;
3139
  }
3140
};
3141
 
3142
/// This represents '#pragma omp target data' directive.
3143
///
3144
/// \code
3145
/// #pragma omp target data device(0) if(a) map(b[:])
3146
/// \endcode
3147
/// In this example directive '#pragma omp target data' has clauses 'device'
3148
/// with the value '0', 'if' with condition 'a' and 'map' with array
3149
/// section 'b[:]'.
3150
///
3151
class OMPTargetDataDirective : public OMPExecutableDirective {
3152
  friend class ASTStmtReader;
3153
  friend class OMPExecutableDirective;
3154
  /// Build directive with the given start and end location.
3155
  ///
3156
  /// \param StartLoc Starting location of the directive kind.
3157
  /// \param EndLoc Ending Location of the directive.
3158
  ///
3159
  OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3160
      : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3161
                               llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3162
 
3163
  /// Build an empty directive.
3164
  ///
3165
  explicit OMPTargetDataDirective()
3166
      : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3167
                               llvm::omp::OMPD_target_data, SourceLocation(),
3168
                               SourceLocation()) {}
3169
 
3170
public:
3171
  /// Creates directive with a list of \a Clauses.
3172
  ///
3173
  /// \param C AST context.
3174
  /// \param StartLoc Starting location of the directive kind.
3175
  /// \param EndLoc Ending Location of the directive.
3176
  /// \param Clauses List of clauses.
3177
  /// \param AssociatedStmt Statement, associated with the directive.
3178
  ///
3179
  static OMPTargetDataDirective *
3180
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3181
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3182
 
3183
  /// Creates an empty directive with the place for \a N clauses.
3184
  ///
3185
  /// \param C AST context.
3186
  /// \param N The number of clauses.
3187
  ///
3188
  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3189
                                             EmptyShell);
3190
 
3191
  static bool classof(const Stmt *T) {
3192
    return T->getStmtClass() == OMPTargetDataDirectiveClass;
3193
  }
3194
};
3195
 
3196
/// This represents '#pragma omp target enter data' directive.
3197
///
3198
/// \code
3199
/// #pragma omp target enter data device(0) if(a) map(b[:])
3200
/// \endcode
3201
/// In this example directive '#pragma omp target enter data' has clauses
3202
/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3203
/// section 'b[:]'.
3204
///
3205
class OMPTargetEnterDataDirective : public OMPExecutableDirective {
3206
  friend class ASTStmtReader;
3207
  friend class OMPExecutableDirective;
3208
  /// Build directive with the given start and end location.
3209
  ///
3210
  /// \param StartLoc Starting location of the directive kind.
3211
  /// \param EndLoc Ending Location of the directive.
3212
  ///
3213
  OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3214
      : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3215
                               llvm::omp::OMPD_target_enter_data, StartLoc,
3216
                               EndLoc) {}
3217
 
3218
  /// Build an empty directive.
3219
  ///
3220
  explicit OMPTargetEnterDataDirective()
3221
      : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3222
                               llvm::omp::OMPD_target_enter_data,
3223
                               SourceLocation(), SourceLocation()) {}
3224
 
3225
public:
3226
  /// Creates directive with a list of \a Clauses.
3227
  ///
3228
  /// \param C AST context.
3229
  /// \param StartLoc Starting location of the directive kind.
3230
  /// \param EndLoc Ending Location of the directive.
3231
  /// \param Clauses List of clauses.
3232
  /// \param AssociatedStmt Statement, associated with the directive.
3233
  ///
3234
  static OMPTargetEnterDataDirective *
3235
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3236
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3237
 
3238
  /// Creates an empty directive with the place for \a N clauses.
3239
  ///
3240
  /// \param C AST context.
3241
  /// \param N The number of clauses.
3242
  ///
3243
  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3244
                                                  unsigned N, EmptyShell);
3245
 
3246
  static bool classof(const Stmt *T) {
3247
    return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3248
  }
3249
};
3250
 
3251
/// This represents '#pragma omp target exit data' directive.
3252
///
3253
/// \code
3254
/// #pragma omp target exit data device(0) if(a) map(b[:])
3255
/// \endcode
3256
/// In this example directive '#pragma omp target exit data' has clauses
3257
/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3258
/// section 'b[:]'.
3259
///
3260
class OMPTargetExitDataDirective : public OMPExecutableDirective {
3261
  friend class ASTStmtReader;
3262
  friend class OMPExecutableDirective;
3263
  /// Build directive with the given start and end location.
3264
  ///
3265
  /// \param StartLoc Starting location of the directive kind.
3266
  /// \param EndLoc Ending Location of the directive.
3267
  ///
3268
  OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3269
      : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3270
                               llvm::omp::OMPD_target_exit_data, StartLoc,
3271
                               EndLoc) {}
3272
 
3273
  /// Build an empty directive.
3274
  ///
3275
  explicit OMPTargetExitDataDirective()
3276
      : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3277
                               llvm::omp::OMPD_target_exit_data,
3278
                               SourceLocation(), SourceLocation()) {}
3279
 
3280
public:
3281
  /// Creates directive with a list of \a Clauses.
3282
  ///
3283
  /// \param C AST context.
3284
  /// \param StartLoc Starting location of the directive kind.
3285
  /// \param EndLoc Ending Location of the directive.
3286
  /// \param Clauses List of clauses.
3287
  /// \param AssociatedStmt Statement, associated with the directive.
3288
  ///
3289
  static OMPTargetExitDataDirective *
3290
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3291
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3292
 
3293
  /// Creates an empty directive with the place for \a N clauses.
3294
  ///
3295
  /// \param C AST context.
3296
  /// \param N The number of clauses.
3297
  ///
3298
  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3299
                                                 unsigned N, EmptyShell);
3300
 
3301
  static bool classof(const Stmt *T) {
3302
    return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3303
  }
3304
};
3305
 
3306
/// This represents '#pragma omp target parallel' directive.
3307
///
3308
/// \code
3309
/// #pragma omp target parallel if(a)
3310
/// \endcode
3311
/// In this example directive '#pragma omp target parallel' has clause 'if' with
3312
/// condition 'a'.
3313
///
3314
class OMPTargetParallelDirective : public OMPExecutableDirective {
3315
  friend class ASTStmtReader;
3316
  friend class OMPExecutableDirective;
3317
  /// true if the construct has inner cancel directive.
3318
  bool HasCancel = false;
3319
 
3320
  /// Build directive with the given start and end location.
3321
  ///
3322
  /// \param StartLoc Starting location of the directive kind.
3323
  /// \param EndLoc Ending location of the directive.
3324
  ///
3325
  OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3326
      : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3327
                               llvm::omp::OMPD_target_parallel, StartLoc,
3328
                               EndLoc) {}
3329
 
3330
  /// Build an empty directive.
3331
  ///
3332
  explicit OMPTargetParallelDirective()
3333
      : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3334
                               llvm::omp::OMPD_target_parallel,
3335
                               SourceLocation(), SourceLocation()) {}
3336
 
3337
  /// Sets special task reduction descriptor.
3338
  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3339
  /// Set cancel state.
3340
  void setHasCancel(bool Has) { HasCancel = Has; }
3341
 
3342
public:
3343
  /// Creates directive with a list of \a Clauses.
3344
  ///
3345
  /// \param C AST context.
3346
  /// \param StartLoc Starting location of the directive kind.
3347
  /// \param EndLoc Ending Location of the directive.
3348
  /// \param Clauses List of clauses.
3349
  /// \param AssociatedStmt Statement, associated with the directive.
3350
  /// \param TaskRedRef Task reduction special reference expression to handle
3351
  /// taskgroup descriptor.
3352
  /// \param HasCancel true if this directive has inner cancel directive.
3353
  ///
3354
  static OMPTargetParallelDirective *
3355
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3356
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3357
         bool HasCancel);
3358
 
3359
  /// Creates an empty directive with the place for \a NumClauses
3360
  /// clauses.
3361
  ///
3362
  /// \param C AST context.
3363
  /// \param NumClauses Number of clauses.
3364
  ///
3365
  static OMPTargetParallelDirective *
3366
  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3367
 
3368
  /// Returns special task reduction reference expression.
3369
  Expr *getTaskReductionRefExpr() {
3370
    return cast_or_null<Expr>(Data->getChildren()[0]);
3371
  }
3372
  const Expr *getTaskReductionRefExpr() const {
3373
    return const_cast<OMPTargetParallelDirective *>(this)
3374
        ->getTaskReductionRefExpr();
3375
  }
3376
 
3377
  /// Return true if current directive has inner cancel directive.
3378
  bool hasCancel() const { return HasCancel; }
3379
 
3380
  static bool classof(const Stmt *T) {
3381
    return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3382
  }
3383
};
3384
 
3385
/// This represents '#pragma omp target parallel for' directive.
3386
///
3387
/// \code
3388
/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3389
/// \endcode
3390
/// In this example directive '#pragma omp target parallel for' has clauses
3391
/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3392
/// and variables 'c' and 'd'.
3393
///
3394
class OMPTargetParallelForDirective : public OMPLoopDirective {
3395
  friend class ASTStmtReader;
3396
  friend class OMPExecutableDirective;
3397
 
3398
  /// true if current region has inner cancel directive.
3399
  bool HasCancel = false;
3400
 
3401
  /// Build directive with the given start and end location.
3402
  ///
3403
  /// \param StartLoc Starting location of the directive kind.
3404
  /// \param EndLoc Ending location of the directive.
3405
  /// \param CollapsedNum Number of collapsed nested loops.
3406
  ///
3407
  OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3408
                                unsigned CollapsedNum)
3409
      : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3410
                         llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3411
                         CollapsedNum) {}
3412
 
3413
  /// Build an empty directive.
3414
  ///
3415
  /// \param CollapsedNum Number of collapsed nested loops.
3416
  ///
3417
  explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3418
      : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3419
                         llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3420
                         SourceLocation(), CollapsedNum) {}
3421
 
3422
  /// Sets special task reduction descriptor.
3423
  void setTaskReductionRefExpr(Expr *E) {
3424
    Data->getChildren()[numLoopChildren(
3425
        getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3426
  }
3427
 
3428
  /// Set cancel state.
3429
  void setHasCancel(bool Has) { HasCancel = Has; }
3430
 
3431
public:
3432
  /// Creates directive with a list of \a Clauses.
3433
  ///
3434
  /// \param C AST context.
3435
  /// \param StartLoc Starting location of the directive kind.
3436
  /// \param EndLoc Ending Location of the directive.
3437
  /// \param CollapsedNum Number of collapsed loops.
3438
  /// \param Clauses List of clauses.
3439
  /// \param AssociatedStmt Statement, associated with the directive.
3440
  /// \param Exprs Helper expressions for CodeGen.
3441
  /// \param TaskRedRef Task reduction special reference expression to handle
3442
  /// taskgroup descriptor.
3443
  /// \param HasCancel true if current directive has inner cancel directive.
3444
  ///
3445
  static OMPTargetParallelForDirective *
3446
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3447
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3448
         Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3449
         bool HasCancel);
3450
 
3451
  /// Creates an empty directive with the place
3452
  /// for \a NumClauses clauses.
3453
  ///
3454
  /// \param C AST context.
3455
  /// \param CollapsedNum Number of collapsed nested loops.
3456
  /// \param NumClauses Number of clauses.
3457
  ///
3458
  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3459
                                                    unsigned NumClauses,
3460
                                                    unsigned CollapsedNum,
3461
                                                    EmptyShell);
3462
 
3463
  /// Returns special task reduction reference expression.
3464
  Expr *getTaskReductionRefExpr() {
3465
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3466
        getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3467
  }
3468
  const Expr *getTaskReductionRefExpr() const {
3469
    return const_cast<OMPTargetParallelForDirective *>(this)
3470
        ->getTaskReductionRefExpr();
3471
  }
3472
 
3473
  /// Return true if current directive has inner cancel directive.
3474
  bool hasCancel() const { return HasCancel; }
3475
 
3476
  static bool classof(const Stmt *T) {
3477
    return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3478
  }
3479
};
3480
 
3481
/// This represents '#pragma omp teams' directive.
3482
///
3483
/// \code
3484
/// #pragma omp teams if(a)
3485
/// \endcode
3486
/// In this example directive '#pragma omp teams' has clause 'if' with
3487
/// condition 'a'.
3488
///
3489
class OMPTeamsDirective : public OMPExecutableDirective {
3490
  friend class ASTStmtReader;
3491
  friend class OMPExecutableDirective;
3492
  /// Build directive with the given start and end location.
3493
  ///
3494
  /// \param StartLoc Starting location of the directive kind.
3495
  /// \param EndLoc Ending location of the directive.
3496
  ///
3497
  OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3498
      : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3499
                               StartLoc, EndLoc) {}
3500
 
3501
  /// Build an empty directive.
3502
  ///
3503
  explicit OMPTeamsDirective()
3504
      : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3505
                               SourceLocation(), SourceLocation()) {}
3506
 
3507
public:
3508
  /// Creates directive with a list of \a Clauses.
3509
  ///
3510
  /// \param C AST context.
3511
  /// \param StartLoc Starting location of the directive kind.
3512
  /// \param EndLoc Ending Location of the directive.
3513
  /// \param Clauses List of clauses.
3514
  /// \param AssociatedStmt Statement, associated with the directive.
3515
  ///
3516
  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3517
                                   SourceLocation EndLoc,
3518
                                   ArrayRef<OMPClause *> Clauses,
3519
                                   Stmt *AssociatedStmt);
3520
 
3521
  /// Creates an empty directive with the place for \a NumClauses
3522
  /// clauses.
3523
  ///
3524
  /// \param C AST context.
3525
  /// \param NumClauses Number of clauses.
3526
  ///
3527
  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3528
                                        unsigned NumClauses, EmptyShell);
3529
 
3530
  static bool classof(const Stmt *T) {
3531
    return T->getStmtClass() == OMPTeamsDirectiveClass;
3532
  }
3533
};
3534
 
3535
/// This represents '#pragma omp cancellation point' directive.
3536
///
3537
/// \code
3538
/// #pragma omp cancellation point for
3539
/// \endcode
3540
///
3541
/// In this example a cancellation point is created for innermost 'for' region.
3542
class OMPCancellationPointDirective : public OMPExecutableDirective {
3543
  friend class ASTStmtReader;
3544
  friend class OMPExecutableDirective;
3545
  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3546
  /// Build directive with the given start and end location.
3547
  ///
3548
  /// \param StartLoc Starting location of the directive kind.
3549
  /// \param EndLoc Ending location of the directive.
3550
  /// statements and child expressions.
3551
  ///
3552
  OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3553
      : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3554
                               llvm::omp::OMPD_cancellation_point, StartLoc,
3555
                               EndLoc) {}
3556
 
3557
  /// Build an empty directive.
3558
  explicit OMPCancellationPointDirective()
3559
      : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3560
                               llvm::omp::OMPD_cancellation_point,
3561
                               SourceLocation(), SourceLocation()) {}
3562
 
3563
  /// Set cancel region for current cancellation point.
3564
  /// \param CR Cancellation region.
3565
  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3566
 
3567
public:
3568
  /// Creates directive.
3569
  ///
3570
  /// \param C AST context.
3571
  /// \param StartLoc Starting location of the directive kind.
3572
  /// \param EndLoc Ending Location of the directive.
3573
  ///
3574
  static OMPCancellationPointDirective *
3575
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3576
         OpenMPDirectiveKind CancelRegion);
3577
 
3578
  /// Creates an empty directive.
3579
  ///
3580
  /// \param C AST context.
3581
  ///
3582
  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3583
                                                    EmptyShell);
3584
 
3585
  /// Get cancellation region for the current cancellation point.
3586
  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3587
 
3588
  static bool classof(const Stmt *T) {
3589
    return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3590
  }
3591
};
3592
 
3593
/// This represents '#pragma omp cancel' directive.
3594
///
3595
/// \code
3596
/// #pragma omp cancel for
3597
/// \endcode
3598
///
3599
/// In this example a cancel is created for innermost 'for' region.
3600
class OMPCancelDirective : public OMPExecutableDirective {
3601
  friend class ASTStmtReader;
3602
  friend class OMPExecutableDirective;
3603
  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3604
  /// Build directive with the given start and end location.
3605
  ///
3606
  /// \param StartLoc Starting location of the directive kind.
3607
  /// \param EndLoc Ending location of the directive.
3608
  ///
3609
  OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3610
      : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3611
                               StartLoc, EndLoc) {}
3612
 
3613
  /// Build an empty directive.
3614
  ///
3615
  explicit OMPCancelDirective()
3616
      : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3617
                               SourceLocation(), SourceLocation()) {}
3618
 
3619
  /// Set cancel region for current cancellation point.
3620
  /// \param CR Cancellation region.
3621
  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3622
 
3623
public:
3624
  /// Creates directive.
3625
  ///
3626
  /// \param C AST context.
3627
  /// \param StartLoc Starting location of the directive kind.
3628
  /// \param EndLoc Ending Location of the directive.
3629
  /// \param Clauses List of clauses.
3630
  ///
3631
  static OMPCancelDirective *
3632
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3633
         ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3634
 
3635
  /// Creates an empty directive.
3636
  ///
3637
  /// \param C AST context.
3638
  /// \param NumClauses Number of clauses.
3639
  ///
3640
  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3641
                                         unsigned NumClauses, EmptyShell);
3642
 
3643
  /// Get cancellation region for the current cancellation point.
3644
  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3645
 
3646
  static bool classof(const Stmt *T) {
3647
    return T->getStmtClass() == OMPCancelDirectiveClass;
3648
  }
3649
};
3650
 
3651
/// This represents '#pragma omp taskloop' directive.
3652
///
3653
/// \code
3654
/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3655
/// \endcode
3656
/// In this example directive '#pragma omp taskloop' has clauses 'private'
3657
/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3658
/// 'num_tasks' with expression 'num'.
3659
///
3660
class OMPTaskLoopDirective : public OMPLoopDirective {
3661
  friend class ASTStmtReader;
3662
  friend class OMPExecutableDirective;
3663
  /// true if the construct has inner cancel directive.
3664
  bool HasCancel = false;
3665
 
3666
  /// Build directive with the given start and end location.
3667
  ///
3668
  /// \param StartLoc Starting location of the directive kind.
3669
  /// \param EndLoc Ending location of the directive.
3670
  /// \param CollapsedNum Number of collapsed nested loops.
3671
  ///
3672
  OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3673
                       unsigned CollapsedNum)
3674
      : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3675
                         StartLoc, EndLoc, CollapsedNum) {}
3676
 
3677
  /// Build an empty directive.
3678
  ///
3679
  /// \param CollapsedNum Number of collapsed nested loops.
3680
  ///
3681
  explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3682
      : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3683
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
3684
 
3685
  /// Set cancel state.
3686
  void setHasCancel(bool Has) { HasCancel = Has; }
3687
 
3688
public:
3689
  /// Creates directive with a list of \a Clauses.
3690
  ///
3691
  /// \param C AST context.
3692
  /// \param StartLoc Starting location of the directive kind.
3693
  /// \param EndLoc Ending Location of the directive.
3694
  /// \param CollapsedNum Number of collapsed loops.
3695
  /// \param Clauses List of clauses.
3696
  /// \param AssociatedStmt Statement, associated with the directive.
3697
  /// \param Exprs Helper expressions for CodeGen.
3698
  /// \param HasCancel true if this directive has inner cancel directive.
3699
  ///
3700
  static OMPTaskLoopDirective *
3701
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3702
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3703
         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3704
 
3705
  /// Creates an empty directive with the place
3706
  /// for \a NumClauses clauses.
3707
  ///
3708
  /// \param C AST context.
3709
  /// \param CollapsedNum Number of collapsed nested loops.
3710
  /// \param NumClauses Number of clauses.
3711
  ///
3712
  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3713
                                           unsigned NumClauses,
3714
                                           unsigned CollapsedNum, EmptyShell);
3715
 
3716
  /// Return true if current directive has inner cancel directive.
3717
  bool hasCancel() const { return HasCancel; }
3718
 
3719
  static bool classof(const Stmt *T) {
3720
    return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3721
  }
3722
};
3723
 
3724
/// This represents '#pragma omp taskloop simd' directive.
3725
///
3726
/// \code
3727
/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3728
/// \endcode
3729
/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3730
/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3731
/// 'num_tasks' with expression 'num'.
3732
///
3733
class OMPTaskLoopSimdDirective : public OMPLoopDirective {
3734
  friend class ASTStmtReader;
3735
  friend class OMPExecutableDirective;
3736
  /// Build directive with the given start and end location.
3737
  ///
3738
  /// \param StartLoc Starting location of the directive kind.
3739
  /// \param EndLoc Ending location of the directive.
3740
  /// \param CollapsedNum Number of collapsed nested loops.
3741
  ///
3742
  OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3743
                           unsigned CollapsedNum)
3744
      : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3745
                         llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3746
                         CollapsedNum) {}
3747
 
3748
  /// Build an empty directive.
3749
  ///
3750
  /// \param CollapsedNum Number of collapsed nested loops.
3751
  ///
3752
  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3753
      : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3754
                         llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3755
                         SourceLocation(), CollapsedNum) {}
3756
 
3757
public:
3758
  /// Creates directive with a list of \a Clauses.
3759
  ///
3760
  /// \param C AST context.
3761
  /// \param StartLoc Starting location of the directive kind.
3762
  /// \param EndLoc Ending Location of the directive.
3763
  /// \param CollapsedNum Number of collapsed loops.
3764
  /// \param Clauses List of clauses.
3765
  /// \param AssociatedStmt Statement, associated with the directive.
3766
  /// \param Exprs Helper expressions for CodeGen.
3767
  ///
3768
  static OMPTaskLoopSimdDirective *
3769
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3770
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3771
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3772
 
3773
  /// Creates an empty directive with the place
3774
  /// for \a NumClauses clauses.
3775
  ///
3776
  /// \param C AST context.
3777
  /// \param CollapsedNum Number of collapsed nested loops.
3778
  /// \param NumClauses Number of clauses.
3779
  ///
3780
  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3781
                                               unsigned NumClauses,
3782
                                               unsigned CollapsedNum,
3783
                                               EmptyShell);
3784
 
3785
  static bool classof(const Stmt *T) {
3786
    return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3787
  }
3788
};
3789
 
3790
/// This represents '#pragma omp master taskloop' directive.
3791
///
3792
/// \code
3793
/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3794
/// \endcode
3795
/// In this example directive '#pragma omp master taskloop' has clauses
3796
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3797
/// and 'num_tasks' with expression 'num'.
3798
///
3799
class OMPMasterTaskLoopDirective : public OMPLoopDirective {
3800
  friend class ASTStmtReader;
3801
  friend class OMPExecutableDirective;
3802
  /// true if the construct has inner cancel directive.
3803
  bool HasCancel = false;
3804
 
3805
  /// Build directive with the given start and end location.
3806
  ///
3807
  /// \param StartLoc Starting location of the directive kind.
3808
  /// \param EndLoc Ending location of the directive.
3809
  /// \param CollapsedNum Number of collapsed nested loops.
3810
  ///
3811
  OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3812
                             unsigned CollapsedNum)
3813
      : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3814
                         llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3815
                         CollapsedNum) {}
3816
 
3817
  /// Build an empty directive.
3818
  ///
3819
  /// \param CollapsedNum Number of collapsed nested loops.
3820
  ///
3821
  explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3822
      : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3823
                         llvm::omp::OMPD_master_taskloop, SourceLocation(),
3824
                         SourceLocation(), CollapsedNum) {}
3825
 
3826
  /// Set cancel state.
3827
  void setHasCancel(bool Has) { HasCancel = Has; }
3828
 
3829
public:
3830
  /// Creates directive with a list of \a Clauses.
3831
  ///
3832
  /// \param C AST context.
3833
  /// \param StartLoc Starting location of the directive kind.
3834
  /// \param EndLoc Ending Location of the directive.
3835
  /// \param CollapsedNum Number of collapsed loops.
3836
  /// \param Clauses List of clauses.
3837
  /// \param AssociatedStmt Statement, associated with the directive.
3838
  /// \param Exprs Helper expressions for CodeGen.
3839
  /// \param HasCancel true if this directive has inner cancel directive.
3840
  ///
3841
  static OMPMasterTaskLoopDirective *
3842
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3843
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3844
         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3845
 
3846
  /// Creates an empty directive with the place
3847
  /// for \a NumClauses clauses.
3848
  ///
3849
  /// \param C AST context.
3850
  /// \param CollapsedNum Number of collapsed nested loops.
3851
  /// \param NumClauses Number of clauses.
3852
  ///
3853
  static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3854
                                                 unsigned NumClauses,
3855
                                                 unsigned CollapsedNum,
3856
                                                 EmptyShell);
3857
 
3858
  /// Return true if current directive has inner cancel directive.
3859
  bool hasCancel() const { return HasCancel; }
3860
 
3861
  static bool classof(const Stmt *T) {
3862
    return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3863
  }
3864
};
3865
 
3866
/// This represents '#pragma omp masked taskloop' directive.
3867
///
3868
/// \code
3869
/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3870
/// \endcode
3871
/// In this example directive '#pragma omp masked taskloop' has clauses
3872
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3873
/// and 'num_tasks' with expression 'num'.
3874
///
3875
class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
3876
  friend class ASTStmtReader;
3877
  friend class OMPExecutableDirective;
3878
  /// true if the construct has inner cancel directive.
3879
  bool HasCancel = false;
3880
 
3881
  /// Build directive with the given start and end location.
3882
  ///
3883
  /// \param StartLoc Starting location of the directive kind.
3884
  /// \param EndLoc Ending location of the directive.
3885
  /// \param CollapsedNum Number of collapsed nested loops.
3886
  ///
3887
  OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3888
                             unsigned CollapsedNum)
3889
      : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3890
                         llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3891
                         CollapsedNum) {}
3892
 
3893
  /// Build an empty directive.
3894
  ///
3895
  /// \param CollapsedNum Number of collapsed nested loops.
3896
  ///
3897
  explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3898
      : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3899
                         llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3900
                         SourceLocation(), CollapsedNum) {}
3901
 
3902
  /// Set cancel state.
3903
  void setHasCancel(bool Has) { HasCancel = Has; }
3904
 
3905
public:
3906
  /// Creates directive with a list of \a Clauses.
3907
  ///
3908
  /// \param C AST context.
3909
  /// \param StartLoc Starting location of the directive kind.
3910
  /// \param EndLoc Ending Location of the directive.
3911
  /// \param CollapsedNum Number of collapsed loops.
3912
  /// \param Clauses List of clauses.
3913
  /// \param AssociatedStmt Statement, associated with the directive.
3914
  /// \param Exprs Helper expressions for CodeGen.
3915
  /// \param HasCancel true if this directive has inner cancel directive.
3916
  ///
3917
  static OMPMaskedTaskLoopDirective *
3918
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3919
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3920
         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3921
 
3922
  /// Creates an empty directive with the place
3923
  /// for \a NumClauses clauses.
3924
  ///
3925
  /// \param C AST context.
3926
  /// \param CollapsedNum Number of collapsed nested loops.
3927
  /// \param NumClauses Number of clauses.
3928
  ///
3929
  static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3930
                                                 unsigned NumClauses,
3931
                                                 unsigned CollapsedNum,
3932
                                                 EmptyShell);
3933
 
3934
  /// Return true if current directive has inner cancel directive.
3935
  bool hasCancel() const { return HasCancel; }
3936
 
3937
  static bool classof(const Stmt *T) {
3938
    return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3939
  }
3940
};
3941
 
3942
/// This represents '#pragma omp master taskloop simd' directive.
3943
///
3944
/// \code
3945
/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3946
/// \endcode
3947
/// In this example directive '#pragma omp master taskloop simd' has clauses
3948
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3949
/// and 'num_tasks' with expression 'num'.
3950
///
3951
class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
3952
  friend class ASTStmtReader;
3953
  friend class OMPExecutableDirective;
3954
  /// Build directive with the given start and end location.
3955
  ///
3956
  /// \param StartLoc Starting location of the directive kind.
3957
  /// \param EndLoc Ending location of the directive.
3958
  /// \param CollapsedNum Number of collapsed nested loops.
3959
  ///
3960
  OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3961
                                 unsigned CollapsedNum)
3962
      : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3963
                         llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3964
                         CollapsedNum) {}
3965
 
3966
  /// Build an empty directive.
3967
  ///
3968
  /// \param CollapsedNum Number of collapsed nested loops.
3969
  ///
3970
  explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3971
      : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3972
                         llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3973
                         SourceLocation(), CollapsedNum) {}
3974
 
3975
public:
3976
  /// Creates directive with a list of \p Clauses.
3977
  ///
3978
  /// \param C AST context.
3979
  /// \param StartLoc Starting location of the directive kind.
3980
  /// \param EndLoc Ending Location of the directive.
3981
  /// \param CollapsedNum Number of collapsed loops.
3982
  /// \param Clauses List of clauses.
3983
  /// \param AssociatedStmt Statement, associated with the directive.
3984
  /// \param Exprs Helper expressions for CodeGen.
3985
  ///
3986
  static OMPMasterTaskLoopSimdDirective *
3987
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3988
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3989
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3990
 
3991
  /// Creates an empty directive with the place for \p NumClauses clauses.
3992
  ///
3993
  /// \param C AST context.
3994
  /// \param CollapsedNum Number of collapsed nested loops.
3995
  /// \param NumClauses Number of clauses.
3996
  ///
3997
  static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3998
                                                     unsigned NumClauses,
3999
                                                     unsigned CollapsedNum,
4000
                                                     EmptyShell);
4001
 
4002
  static bool classof(const Stmt *T) {
4003
    return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4004
  }
4005
};
4006
 
4007
/// This represents '#pragma omp masked taskloop simd' directive.
4008
///
4009
/// \code
4010
/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4011
/// \endcode
4012
/// In this example directive '#pragma omp masked taskloop simd' has clauses
4013
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4014
/// and 'num_tasks' with expression 'num'.
4015
///
4016
class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4017
  friend class ASTStmtReader;
4018
  friend class OMPExecutableDirective;
4019
  /// Build directive with the given start and end location.
4020
  ///
4021
  /// \param StartLoc Starting location of the directive kind.
4022
  /// \param EndLoc Ending location of the directive.
4023
  /// \param CollapsedNum Number of collapsed nested loops.
4024
  ///
4025
  OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4026
                                 unsigned CollapsedNum)
4027
      : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4028
                         llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4029
                         CollapsedNum) {}
4030
 
4031
  /// Build an empty directive.
4032
  ///
4033
  /// \param CollapsedNum Number of collapsed nested loops.
4034
  ///
4035
  explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4036
      : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4037
                         llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4038
                         SourceLocation(), CollapsedNum) {}
4039
 
4040
public:
4041
  /// Creates directive with a list of \p Clauses.
4042
  ///
4043
  /// \param C AST context.
4044
  /// \param StartLoc Starting location of the directive kind.
4045
  /// \param EndLoc Ending Location of the directive.
4046
  /// \param CollapsedNum Number of collapsed loops.
4047
  /// \param Clauses List of clauses.
4048
  /// \param AssociatedStmt Statement, associated with the directive.
4049
  /// \param Exprs Helper expressions for CodeGen.
4050
  ///
4051
  static OMPMaskedTaskLoopSimdDirective *
4052
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4053
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4054
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4055
 
4056
  /// Creates an empty directive with the place for \p NumClauses clauses.
4057
  ///
4058
  /// \param C AST context.
4059
  /// \param CollapsedNum Number of collapsed nested loops.
4060
  /// \param NumClauses Number of clauses.
4061
  ///
4062
  static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4063
                                                     unsigned NumClauses,
4064
                                                     unsigned CollapsedNum,
4065
                                                     EmptyShell);
4066
 
4067
  static bool classof(const Stmt *T) {
4068
    return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4069
  }
4070
};
4071
 
4072
/// This represents '#pragma omp parallel master taskloop' directive.
4073
///
4074
/// \code
4075
/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4076
/// num_tasks(num)
4077
/// \endcode
4078
/// In this example directive '#pragma omp parallel master taskloop' has clauses
4079
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4080
/// and 'num_tasks' with expression 'num'.
4081
///
4082
class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
4083
  friend class ASTStmtReader;
4084
  friend class OMPExecutableDirective;
4085
  /// true if the construct has inner cancel directive.
4086
  bool HasCancel = false;
4087
 
4088
  /// Build directive with the given start and end location.
4089
  ///
4090
  /// \param StartLoc Starting location of the directive kind.
4091
  /// \param EndLoc Ending location of the directive.
4092
  /// \param CollapsedNum Number of collapsed nested loops.
4093
  ///
4094
  OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
4095
                                     SourceLocation EndLoc,
4096
                                     unsigned CollapsedNum)
4097
      : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4098
                         llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4099
                         EndLoc, CollapsedNum) {}
4100
 
4101
  /// Build an empty directive.
4102
  ///
4103
  /// \param CollapsedNum Number of collapsed nested loops.
4104
  ///
4105
  explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4106
      : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4107
                         llvm::omp::OMPD_parallel_master_taskloop,
4108
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4109
 
4110
  /// Set cancel state.
4111
  void setHasCancel(bool Has) { HasCancel = Has; }
4112
 
4113
public:
4114
  /// Creates directive with a list of \a Clauses.
4115
  ///
4116
  /// \param C AST context.
4117
  /// \param StartLoc Starting location of the directive kind.
4118
  /// \param EndLoc Ending Location of the directive.
4119
  /// \param CollapsedNum Number of collapsed loops.
4120
  /// \param Clauses List of clauses.
4121
  /// \param AssociatedStmt Statement, associated with the directive.
4122
  /// \param Exprs Helper expressions for CodeGen.
4123
  /// \param HasCancel true if this directive has inner cancel directive.
4124
  ///
4125
  static OMPParallelMasterTaskLoopDirective *
4126
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4127
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4128
         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4129
 
4130
  /// Creates an empty directive with the place
4131
  /// for \a NumClauses clauses.
4132
  ///
4133
  /// \param C AST context.
4134
  /// \param CollapsedNum Number of collapsed nested loops.
4135
  /// \param NumClauses Number of clauses.
4136
  ///
4137
  static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4138
                                                         unsigned NumClauses,
4139
                                                         unsigned CollapsedNum,
4140
                                                         EmptyShell);
4141
 
4142
  /// Return true if current directive has inner cancel directive.
4143
  bool hasCancel() const { return HasCancel; }
4144
 
4145
  static bool classof(const Stmt *T) {
4146
    return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4147
  }
4148
};
4149
 
4150
/// This represents '#pragma omp parallel masked taskloop' directive.
4151
///
4152
/// \code
4153
/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4154
/// num_tasks(num)
4155
/// \endcode
4156
/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4157
/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4158
/// and 'num_tasks' with expression 'num'.
4159
///
4160
class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
4161
  friend class ASTStmtReader;
4162
  friend class OMPExecutableDirective;
4163
  /// true if the construct has inner cancel directive.
4164
  bool HasCancel = false;
4165
 
4166
  /// Build directive with the given start and end location.
4167
  ///
4168
  /// \param StartLoc Starting location of the directive kind.
4169
  /// \param EndLoc Ending location of the directive.
4170
  /// \param CollapsedNum Number of collapsed nested loops.
4171
  ///
4172
  OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
4173
                                     SourceLocation EndLoc,
4174
                                     unsigned CollapsedNum)
4175
      : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4176
                         llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4177
                         EndLoc, CollapsedNum) {}
4178
 
4179
  /// Build an empty directive.
4180
  ///
4181
  /// \param CollapsedNum Number of collapsed nested loops.
4182
  ///
4183
  explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4184
      : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4185
                         llvm::omp::OMPD_parallel_masked_taskloop,
4186
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4187
 
4188
  /// Set cancel state.
4189
  void setHasCancel(bool Has) { HasCancel = Has; }
4190
 
4191
public:
4192
  /// Creates directive with a list of \a Clauses.
4193
  ///
4194
  /// \param C AST context.
4195
  /// \param StartLoc Starting location of the directive kind.
4196
  /// \param EndLoc Ending Location of the directive.
4197
  /// \param CollapsedNum Number of collapsed loops.
4198
  /// \param Clauses List of clauses.
4199
  /// \param AssociatedStmt Statement, associated with the directive.
4200
  /// \param Exprs Helper expressions for CodeGen.
4201
  /// \param HasCancel true if this directive has inner cancel directive.
4202
  ///
4203
  static OMPParallelMaskedTaskLoopDirective *
4204
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4205
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4206
         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4207
 
4208
  /// Creates an empty directive with the place
4209
  /// for \a NumClauses clauses.
4210
  ///
4211
  /// \param C AST context.
4212
  /// \param CollapsedNum Number of collapsed nested loops.
4213
  /// \param NumClauses Number of clauses.
4214
  ///
4215
  static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4216
                                                         unsigned NumClauses,
4217
                                                         unsigned CollapsedNum,
4218
                                                         EmptyShell);
4219
 
4220
  /// Return true if current directive has inner cancel directive.
4221
  bool hasCancel() const { return HasCancel; }
4222
 
4223
  static bool classof(const Stmt *T) {
4224
    return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4225
  }
4226
};
4227
 
4228
/// This represents '#pragma omp parallel master taskloop simd' directive.
4229
///
4230
/// \code
4231
/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4232
/// num_tasks(num)
4233
/// \endcode
4234
/// In this example directive '#pragma omp parallel master taskloop simd' has
4235
/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4236
/// expression 'val' and 'num_tasks' with expression 'num'.
4237
///
4238
class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
4239
  friend class ASTStmtReader;
4240
  friend class OMPExecutableDirective;
4241
  /// Build directive with the given start and end location.
4242
  ///
4243
  /// \param StartLoc Starting location of the directive kind.
4244
  /// \param EndLoc Ending location of the directive.
4245
  /// \param CollapsedNum Number of collapsed nested loops.
4246
  ///
4247
  OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
4248
                                         SourceLocation EndLoc,
4249
                                         unsigned CollapsedNum)
4250
      : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4251
                         llvm::omp::OMPD_parallel_master_taskloop_simd,
4252
                         StartLoc, EndLoc, CollapsedNum) {}
4253
 
4254
  /// Build an empty directive.
4255
  ///
4256
  /// \param CollapsedNum Number of collapsed nested loops.
4257
  ///
4258
  explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4259
      : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4260
                         llvm::omp::OMPD_parallel_master_taskloop_simd,
4261
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4262
 
4263
public:
4264
  /// Creates directive with a list of \p Clauses.
4265
  ///
4266
  /// \param C AST context.
4267
  /// \param StartLoc Starting location of the directive kind.
4268
  /// \param EndLoc Ending Location of the directive.
4269
  /// \param CollapsedNum Number of collapsed loops.
4270
  /// \param Clauses List of clauses.
4271
  /// \param AssociatedStmt Statement, associated with the directive.
4272
  /// \param Exprs Helper expressions for CodeGen.
4273
  ///
4274
  static OMPParallelMasterTaskLoopSimdDirective *
4275
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4276
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4277
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4278
 
4279
  /// Creates an empty directive with the place
4280
  /// for \a NumClauses clauses.
4281
  ///
4282
  /// \param C AST context.
4283
  /// \param CollapsedNum Number of collapsed nested loops.
4284
  /// \param NumClauses Number of clauses.
4285
  ///
4286
  static OMPParallelMasterTaskLoopSimdDirective *
4287
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4288
              EmptyShell);
4289
 
4290
  static bool classof(const Stmt *T) {
4291
    return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4292
  }
4293
};
4294
 
4295
/// This represents '#pragma omp parallel masked taskloop simd' directive.
4296
///
4297
/// \code
4298
/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4299
/// num_tasks(num)
4300
/// \endcode
4301
/// In this example directive '#pragma omp parallel masked taskloop simd' has
4302
/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4303
/// expression 'val' and 'num_tasks' with expression 'num'.
4304
///
4305
class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4306
  friend class ASTStmtReader;
4307
  friend class OMPExecutableDirective;
4308
  /// Build directive with the given start and end location.
4309
  ///
4310
  /// \param StartLoc Starting location of the directive kind.
4311
  /// \param EndLoc Ending location of the directive.
4312
  /// \param CollapsedNum Number of collapsed nested loops.
4313
  ///
4314
  OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
4315
                                         SourceLocation EndLoc,
4316
                                         unsigned CollapsedNum)
4317
      : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4318
                         llvm::omp::OMPD_parallel_masked_taskloop_simd,
4319
                         StartLoc, EndLoc, CollapsedNum) {}
4320
 
4321
  /// Build an empty directive.
4322
  ///
4323
  /// \param CollapsedNum Number of collapsed nested loops.
4324
  ///
4325
  explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4326
      : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4327
                         llvm::omp::OMPD_parallel_masked_taskloop_simd,
4328
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4329
 
4330
public:
4331
  /// Creates directive with a list of \p Clauses.
4332
  ///
4333
  /// \param C AST context.
4334
  /// \param StartLoc Starting location of the directive kind.
4335
  /// \param EndLoc Ending Location of the directive.
4336
  /// \param CollapsedNum Number of collapsed loops.
4337
  /// \param Clauses List of clauses.
4338
  /// \param AssociatedStmt Statement, associated with the directive.
4339
  /// \param Exprs Helper expressions for CodeGen.
4340
  ///
4341
  static OMPParallelMaskedTaskLoopSimdDirective *
4342
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4343
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4344
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4345
 
4346
  /// Creates an empty directive with the place
4347
  /// for \a NumClauses clauses.
4348
  ///
4349
  /// \param C AST context.
4350
  /// \param CollapsedNum Number of collapsed nested loops.
4351
  /// \param NumClauses Number of clauses.
4352
  ///
4353
  static OMPParallelMaskedTaskLoopSimdDirective *
4354
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4355
              EmptyShell);
4356
 
4357
  static bool classof(const Stmt *T) {
4358
    return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4359
  }
4360
};
4361
 
4362
/// This represents '#pragma omp distribute' directive.
4363
///
4364
/// \code
4365
/// #pragma omp distribute private(a,b)
4366
/// \endcode
4367
/// In this example directive '#pragma omp distribute' has clauses 'private'
4368
/// with the variables 'a' and 'b'
4369
///
4370
class OMPDistributeDirective : public OMPLoopDirective {
4371
  friend class ASTStmtReader;
4372
  friend class OMPExecutableDirective;
4373
 
4374
  /// Build directive with the given start and end location.
4375
  ///
4376
  /// \param StartLoc Starting location of the directive kind.
4377
  /// \param EndLoc Ending location of the directive.
4378
  /// \param CollapsedNum Number of collapsed nested loops.
4379
  ///
4380
  OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4381
                         unsigned CollapsedNum)
4382
      : OMPLoopDirective(OMPDistributeDirectiveClass,
4383
                         llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4384
                         CollapsedNum) {}
4385
 
4386
  /// Build an empty directive.
4387
  ///
4388
  /// \param CollapsedNum Number of collapsed nested loops.
4389
  ///
4390
  explicit OMPDistributeDirective(unsigned CollapsedNum)
4391
      : OMPLoopDirective(OMPDistributeDirectiveClass,
4392
                         llvm::omp::OMPD_distribute, SourceLocation(),
4393
                         SourceLocation(), CollapsedNum) {}
4394
 
4395
public:
4396
  /// Creates directive with a list of \a Clauses.
4397
  ///
4398
  /// \param C AST context.
4399
  /// \param StartLoc Starting location of the directive kind.
4400
  /// \param EndLoc Ending Location of the directive.
4401
  /// \param CollapsedNum Number of collapsed loops.
4402
  /// \param Clauses List of clauses.
4403
  /// \param AssociatedStmt Statement, associated with the directive.
4404
  /// \param Exprs Helper expressions for CodeGen.
4405
  ///
4406
  static OMPDistributeDirective *
4407
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4408
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4409
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4410
 
4411
  /// Creates an empty directive with the place
4412
  /// for \a NumClauses clauses.
4413
  ///
4414
  /// \param C AST context.
4415
  /// \param CollapsedNum Number of collapsed nested loops.
4416
  /// \param NumClauses Number of clauses.
4417
  ///
4418
  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4419
                                             unsigned NumClauses,
4420
                                             unsigned CollapsedNum, EmptyShell);
4421
 
4422
  static bool classof(const Stmt *T) {
4423
    return T->getStmtClass() == OMPDistributeDirectiveClass;
4424
  }
4425
};
4426
 
4427
/// This represents '#pragma omp target update' directive.
4428
///
4429
/// \code
4430
/// #pragma omp target update to(a) from(b) device(1)
4431
/// \endcode
4432
/// In this example directive '#pragma omp target update' has clause 'to' with
4433
/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4434
/// argument '1'.
4435
///
4436
class OMPTargetUpdateDirective : public OMPExecutableDirective {
4437
  friend class ASTStmtReader;
4438
  friend class OMPExecutableDirective;
4439
  /// Build directive with the given start and end location.
4440
  ///
4441
  /// \param StartLoc Starting location of the directive kind.
4442
  /// \param EndLoc Ending Location of the directive.
4443
  ///
4444
  OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
4445
      : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4446
                               llvm::omp::OMPD_target_update, StartLoc,
4447
                               EndLoc) {}
4448
 
4449
  /// Build an empty directive.
4450
  ///
4451
  explicit OMPTargetUpdateDirective()
4452
      : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4453
                               llvm::omp::OMPD_target_update, SourceLocation(),
4454
                               SourceLocation()) {}
4455
 
4456
public:
4457
  /// Creates directive with a list of \a Clauses.
4458
  ///
4459
  /// \param C AST context.
4460
  /// \param StartLoc Starting location of the directive kind.
4461
  /// \param EndLoc Ending Location of the directive.
4462
  /// \param Clauses List of clauses.
4463
  /// \param AssociatedStmt Statement, associated with the directive.
4464
  ///
4465
  static OMPTargetUpdateDirective *
4466
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4467
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4468
 
4469
  /// Creates an empty directive with the place for \a NumClauses
4470
  /// clauses.
4471
  ///
4472
  /// \param C AST context.
4473
  /// \param NumClauses The number of clauses.
4474
  ///
4475
  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4476
                                               unsigned NumClauses, EmptyShell);
4477
 
4478
  static bool classof(const Stmt *T) {
4479
    return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4480
  }
4481
};
4482
 
4483
/// This represents '#pragma omp distribute parallel for' composite
4484
///  directive.
4485
///
4486
/// \code
4487
/// #pragma omp distribute parallel for private(a,b)
4488
/// \endcode
4489
/// In this example directive '#pragma omp distribute parallel for' has clause
4490
/// 'private' with the variables 'a' and 'b'
4491
///
4492
class OMPDistributeParallelForDirective : public OMPLoopDirective {
4493
  friend class ASTStmtReader;
4494
  friend class OMPExecutableDirective;
4495
  /// true if the construct has inner cancel directive.
4496
  bool HasCancel = false;
4497
 
4498
  /// Build directive with the given start and end location.
4499
  ///
4500
  /// \param StartLoc Starting location of the directive kind.
4501
  /// \param EndLoc Ending location of the directive.
4502
  /// \param CollapsedNum Number of collapsed nested loops.
4503
  ///
4504
  OMPDistributeParallelForDirective(SourceLocation StartLoc,
4505
                                    SourceLocation EndLoc,
4506
                                    unsigned CollapsedNum)
4507
      : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4508
                         llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4509
                         EndLoc, CollapsedNum) {}
4510
 
4511
  /// Build an empty directive.
4512
  ///
4513
  /// \param CollapsedNum Number of collapsed nested loops.
4514
  ///
4515
  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4516
      : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4517
                         llvm::omp::OMPD_distribute_parallel_for,
4518
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4519
 
4520
  /// Sets special task reduction descriptor.
4521
  void setTaskReductionRefExpr(Expr *E) {
4522
    Data->getChildren()[numLoopChildren(
4523
        getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4524
  }
4525
 
4526
  /// Set cancel state.
4527
  void setHasCancel(bool Has) { HasCancel = Has; }
4528
 
4529
public:
4530
  /// Creates directive with a list of \a Clauses.
4531
  ///
4532
  /// \param C AST context.
4533
  /// \param StartLoc Starting location of the directive kind.
4534
  /// \param EndLoc Ending Location of the directive.
4535
  /// \param CollapsedNum Number of collapsed loops.
4536
  /// \param Clauses List of clauses.
4537
  /// \param AssociatedStmt Statement, associated with the directive.
4538
  /// \param Exprs Helper expressions for CodeGen.
4539
  /// \param TaskRedRef Task reduction special reference expression to handle
4540
  /// taskgroup descriptor.
4541
  /// \param HasCancel true if this directive has inner cancel directive.
4542
  ///
4543
  static OMPDistributeParallelForDirective *
4544
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4545
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4546
         Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4547
         bool HasCancel);
4548
 
4549
  /// Creates an empty directive with the place
4550
  /// for \a NumClauses clauses.
4551
  ///
4552
  /// \param C AST context.
4553
  /// \param CollapsedNum Number of collapsed nested loops.
4554
  /// \param NumClauses Number of clauses.
4555
  ///
4556
  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4557
                                                        unsigned NumClauses,
4558
                                                        unsigned CollapsedNum,
4559
                                                        EmptyShell);
4560
 
4561
  /// Returns special task reduction reference expression.
4562
  Expr *getTaskReductionRefExpr() {
4563
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4564
        getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4565
  }
4566
  const Expr *getTaskReductionRefExpr() const {
4567
    return const_cast<OMPDistributeParallelForDirective *>(this)
4568
        ->getTaskReductionRefExpr();
4569
  }
4570
 
4571
  /// Return true if current directive has inner cancel directive.
4572
  bool hasCancel() const { return HasCancel; }
4573
 
4574
  static bool classof(const Stmt *T) {
4575
    return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4576
  }
4577
};
4578
 
4579
/// This represents '#pragma omp distribute parallel for simd' composite
4580
/// directive.
4581
///
4582
/// \code
4583
/// #pragma omp distribute parallel for simd private(x)
4584
/// \endcode
4585
/// In this example directive '#pragma omp distribute parallel for simd' has
4586
/// clause 'private' with the variables 'x'
4587
///
4588
class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
4589
  friend class ASTStmtReader;
4590
  friend class OMPExecutableDirective;
4591
 
4592
  /// Build directive with the given start and end location.
4593
  ///
4594
  /// \param StartLoc Starting location of the directive kind.
4595
  /// \param EndLoc Ending location of the directive.
4596
  /// \param CollapsedNum Number of collapsed nested loops.
4597
  ///
4598
  OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
4599
                                        SourceLocation EndLoc,
4600
                                        unsigned CollapsedNum)
4601
      : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4602
                         llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4603
                         EndLoc, CollapsedNum) {}
4604
 
4605
  /// Build an empty directive.
4606
  ///
4607
  /// \param CollapsedNum Number of collapsed nested loops.
4608
  ///
4609
  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4610
      : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4611
                         llvm::omp::OMPD_distribute_parallel_for_simd,
4612
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4613
 
4614
public:
4615
  /// Creates directive with a list of \a Clauses.
4616
  ///
4617
  /// \param C AST context.
4618
  /// \param StartLoc Starting location of the directive kind.
4619
  /// \param EndLoc Ending Location of the directive.
4620
  /// \param CollapsedNum Number of collapsed loops.
4621
  /// \param Clauses List of clauses.
4622
  /// \param AssociatedStmt Statement, associated with the directive.
4623
  /// \param Exprs Helper expressions for CodeGen.
4624
  ///
4625
  static OMPDistributeParallelForSimdDirective *Create(
4626
      const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4627
      unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4628
      Stmt *AssociatedStmt, const HelperExprs &Exprs);
4629
 
4630
  /// Creates an empty directive with the place for \a NumClauses clauses.
4631
  ///
4632
  /// \param C AST context.
4633
  /// \param CollapsedNum Number of collapsed nested loops.
4634
  /// \param NumClauses Number of clauses.
4635
  ///
4636
  static OMPDistributeParallelForSimdDirective *CreateEmpty(
4637
      const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4638
      EmptyShell);
4639
 
4640
  static bool classof(const Stmt *T) {
4641
    return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4642
  }
4643
};
4644
 
4645
/// This represents '#pragma omp distribute simd' composite directive.
4646
///
4647
/// \code
4648
/// #pragma omp distribute simd private(x)
4649
/// \endcode
4650
/// In this example directive '#pragma omp distribute simd' has clause
4651
/// 'private' with the variables 'x'
4652
///
4653
class OMPDistributeSimdDirective final : public OMPLoopDirective {
4654
  friend class ASTStmtReader;
4655
  friend class OMPExecutableDirective;
4656
 
4657
  /// Build directive with the given start and end location.
4658
  ///
4659
  /// \param StartLoc Starting location of the directive kind.
4660
  /// \param EndLoc Ending location of the directive.
4661
  /// \param CollapsedNum Number of collapsed nested loops.
4662
  ///
4663
  OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4664
                             unsigned CollapsedNum)
4665
      : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4666
                         llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4667
                         CollapsedNum) {}
4668
 
4669
  /// Build an empty directive.
4670
  ///
4671
  /// \param CollapsedNum Number of collapsed nested loops.
4672
  ///
4673
  explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4674
      : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4675
                         llvm::omp::OMPD_distribute_simd, SourceLocation(),
4676
                         SourceLocation(), CollapsedNum) {}
4677
 
4678
public:
4679
  /// Creates directive with a list of \a Clauses.
4680
  ///
4681
  /// \param C AST context.
4682
  /// \param StartLoc Starting location of the directive kind.
4683
  /// \param EndLoc Ending Location of the directive.
4684
  /// \param CollapsedNum Number of collapsed loops.
4685
  /// \param Clauses List of clauses.
4686
  /// \param AssociatedStmt Statement, associated with the directive.
4687
  /// \param Exprs Helper expressions for CodeGen.
4688
  ///
4689
  static OMPDistributeSimdDirective *
4690
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4691
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4692
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4693
 
4694
  /// Creates an empty directive with the place for \a NumClauses clauses.
4695
  ///
4696
  /// \param C AST context.
4697
  /// \param CollapsedNum Number of collapsed nested loops.
4698
  /// \param NumClauses Number of clauses.
4699
  ///
4700
  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4701
                                                 unsigned NumClauses,
4702
                                                 unsigned CollapsedNum,
4703
                                                 EmptyShell);
4704
 
4705
  static bool classof(const Stmt *T) {
4706
    return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4707
  }
4708
};
4709
 
4710
/// This represents '#pragma omp target parallel for simd' directive.
4711
///
4712
/// \code
4713
/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4714
/// \endcode
4715
/// In this example directive '#pragma omp target parallel for simd' has clauses
4716
/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4717
/// with the variable 'c'.
4718
///
4719
class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
4720
  friend class ASTStmtReader;
4721
  friend class OMPExecutableDirective;
4722
 
4723
  /// Build directive with the given start and end location.
4724
  ///
4725
  /// \param StartLoc Starting location of the directive kind.
4726
  /// \param EndLoc Ending location of the directive.
4727
  /// \param CollapsedNum Number of collapsed nested loops.
4728
  ///
4729
  OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
4730
                                    SourceLocation EndLoc,
4731
                                    unsigned CollapsedNum)
4732
      : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4733
                         llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4734
                         EndLoc, CollapsedNum) {}
4735
 
4736
  /// Build an empty directive.
4737
  ///
4738
  /// \param CollapsedNum Number of collapsed nested loops.
4739
  ///
4740
  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4741
      : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4742
                         llvm::omp::OMPD_target_parallel_for_simd,
4743
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4744
 
4745
public:
4746
  /// Creates directive with a list of \a Clauses.
4747
  ///
4748
  /// \param C AST context.
4749
  /// \param StartLoc Starting location of the directive kind.
4750
  /// \param EndLoc Ending Location of the directive.
4751
  /// \param CollapsedNum Number of collapsed loops.
4752
  /// \param Clauses List of clauses.
4753
  /// \param AssociatedStmt Statement, associated with the directive.
4754
  /// \param Exprs Helper expressions for CodeGen.
4755
  ///
4756
  static OMPTargetParallelForSimdDirective *
4757
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4758
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4759
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4760
 
4761
  /// Creates an empty directive with the place for \a NumClauses clauses.
4762
  ///
4763
  /// \param C AST context.
4764
  /// \param CollapsedNum Number of collapsed nested loops.
4765
  /// \param NumClauses Number of clauses.
4766
  ///
4767
  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4768
                                                        unsigned NumClauses,
4769
                                                        unsigned CollapsedNum,
4770
                                                        EmptyShell);
4771
 
4772
  static bool classof(const Stmt *T) {
4773
    return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4774
  }
4775
};
4776
 
4777
/// This represents '#pragma omp target simd' directive.
4778
///
4779
/// \code
4780
/// #pragma omp target simd private(a) map(b) safelen(c)
4781
/// \endcode
4782
/// In this example directive '#pragma omp target simd' has clauses 'private'
4783
/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4784
/// the variable 'c'.
4785
///
4786
class OMPTargetSimdDirective final : public OMPLoopDirective {
4787
  friend class ASTStmtReader;
4788
  friend class OMPExecutableDirective;
4789
 
4790
  /// Build directive with the given start and end location.
4791
  ///
4792
  /// \param StartLoc Starting location of the directive kind.
4793
  /// \param EndLoc Ending location of the directive.
4794
  /// \param CollapsedNum Number of collapsed nested loops.
4795
  ///
4796
  OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4797
                         unsigned CollapsedNum)
4798
      : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4799
                         llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4800
                         CollapsedNum) {}
4801
 
4802
  /// Build an empty directive.
4803
  ///
4804
  /// \param CollapsedNum Number of collapsed nested loops.
4805
  ///
4806
  explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4807
      : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4808
                         llvm::omp::OMPD_target_simd, SourceLocation(),
4809
                         SourceLocation(), CollapsedNum) {}
4810
 
4811
public:
4812
  /// Creates directive with a list of \a Clauses.
4813
  ///
4814
  /// \param C AST context.
4815
  /// \param StartLoc Starting location of the directive kind.
4816
  /// \param EndLoc Ending Location of the directive.
4817
  /// \param CollapsedNum Number of collapsed loops.
4818
  /// \param Clauses List of clauses.
4819
  /// \param AssociatedStmt Statement, associated with the directive.
4820
  /// \param Exprs Helper expressions for CodeGen.
4821
  ///
4822
  static OMPTargetSimdDirective *
4823
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4824
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4825
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4826
 
4827
  /// Creates an empty directive with the place for \a NumClauses clauses.
4828
  ///
4829
  /// \param C AST context.
4830
  /// \param CollapsedNum Number of collapsed nested loops.
4831
  /// \param NumClauses Number of clauses.
4832
  ///
4833
  static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4834
                                             unsigned NumClauses,
4835
                                             unsigned CollapsedNum,
4836
                                             EmptyShell);
4837
 
4838
  static bool classof(const Stmt *T) {
4839
    return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4840
  }
4841
};
4842
 
4843
/// This represents '#pragma omp teams distribute' directive.
4844
///
4845
/// \code
4846
/// #pragma omp teams distribute private(a,b)
4847
/// \endcode
4848
/// In this example directive '#pragma omp teams distribute' has clauses
4849
/// 'private' with the variables 'a' and 'b'
4850
///
4851
class OMPTeamsDistributeDirective final : public OMPLoopDirective {
4852
  friend class ASTStmtReader;
4853
  friend class OMPExecutableDirective;
4854
 
4855
  /// Build directive with the given start and end location.
4856
  ///
4857
  /// \param StartLoc Starting location of the directive kind.
4858
  /// \param EndLoc Ending location of the directive.
4859
  /// \param CollapsedNum Number of collapsed nested loops.
4860
  ///
4861
  OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4862
                              unsigned CollapsedNum)
4863
      : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4864
                         llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4865
                         CollapsedNum) {}
4866
 
4867
  /// Build an empty directive.
4868
  ///
4869
  /// \param CollapsedNum Number of collapsed nested loops.
4870
  ///
4871
  explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4872
      : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4873
                         llvm::omp::OMPD_teams_distribute, SourceLocation(),
4874
                         SourceLocation(), CollapsedNum) {}
4875
 
4876
public:
4877
  /// Creates directive with a list of \a Clauses.
4878
  ///
4879
  /// \param C AST context.
4880
  /// \param StartLoc Starting location of the directive kind.
4881
  /// \param EndLoc Ending Location of the directive.
4882
  /// \param CollapsedNum Number of collapsed loops.
4883
  /// \param Clauses List of clauses.
4884
  /// \param AssociatedStmt Statement, associated with the directive.
4885
  /// \param Exprs Helper expressions for CodeGen.
4886
  ///
4887
  static OMPTeamsDistributeDirective *
4888
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4889
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4890
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4891
 
4892
  /// Creates an empty directive with the place for \a NumClauses clauses.
4893
  ///
4894
  /// \param C AST context.
4895
  /// \param CollapsedNum Number of collapsed nested loops.
4896
  /// \param NumClauses Number of clauses.
4897
  ///
4898
  static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4899
                                                  unsigned NumClauses,
4900
                                                  unsigned CollapsedNum,
4901
                                                  EmptyShell);
4902
 
4903
  static bool classof(const Stmt *T) {
4904
    return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4905
  }
4906
};
4907
 
4908
/// This represents '#pragma omp teams distribute simd'
4909
/// combined directive.
4910
///
4911
/// \code
4912
/// #pragma omp teams distribute simd private(a,b)
4913
/// \endcode
4914
/// In this example directive '#pragma omp teams distribute simd'
4915
/// has clause 'private' with the variables 'a' and 'b'
4916
///
4917
class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
4918
  friend class ASTStmtReader;
4919
  friend class OMPExecutableDirective;
4920
 
4921
  /// Build directive with the given start and end location.
4922
  ///
4923
  /// \param StartLoc Starting location of the directive kind.
4924
  /// \param EndLoc Ending location of the directive.
4925
  /// \param CollapsedNum Number of collapsed nested loops.
4926
  ///
4927
  OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
4928
                                  SourceLocation EndLoc, unsigned CollapsedNum)
4929
      : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4930
                         llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4931
                         EndLoc, CollapsedNum) {}
4932
 
4933
  /// Build an empty directive.
4934
  ///
4935
  /// \param CollapsedNum Number of collapsed nested loops.
4936
  ///
4937
  explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4938
      : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4939
                         llvm::omp::OMPD_teams_distribute_simd,
4940
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
4941
 
4942
public:
4943
  /// Creates directive with a list of \a Clauses.
4944
  ///
4945
  /// \param C AST context.
4946
  /// \param StartLoc Starting location of the directive kind.
4947
  /// \param EndLoc Ending Location of the directive.
4948
  /// \param CollapsedNum Number of collapsed loops.
4949
  /// \param Clauses List of clauses.
4950
  /// \param AssociatedStmt Statement, associated with the directive.
4951
  /// \param Exprs Helper expressions for CodeGen.
4952
  ///
4953
  static OMPTeamsDistributeSimdDirective *
4954
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4955
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4956
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4957
 
4958
  /// Creates an empty directive with the place
4959
  /// for \a NumClauses clauses.
4960
  ///
4961
  /// \param C AST context.
4962
  /// \param CollapsedNum Number of collapsed nested loops.
4963
  /// \param NumClauses Number of clauses.
4964
  ///
4965
  static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4966
                                                      unsigned NumClauses,
4967
                                                      unsigned CollapsedNum,
4968
                                                      EmptyShell);
4969
 
4970
  static bool classof(const Stmt *T) {
4971
    return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4972
  }
4973
};
4974
 
4975
/// This represents '#pragma omp teams distribute parallel for simd' composite
4976
/// directive.
4977
///
4978
/// \code
4979
/// #pragma omp teams distribute parallel for simd private(x)
4980
/// \endcode
4981
/// In this example directive '#pragma omp teams distribute parallel for simd'
4982
/// has clause 'private' with the variables 'x'
4983
///
4984
class OMPTeamsDistributeParallelForSimdDirective final
4985
    : public OMPLoopDirective {
4986
  friend class ASTStmtReader;
4987
  friend class OMPExecutableDirective;
4988
 
4989
  /// Build directive with the given start and end location.
4990
  ///
4991
  /// \param StartLoc Starting location of the directive kind.
4992
  /// \param EndLoc Ending location of the directive.
4993
  /// \param CollapsedNum Number of collapsed nested loops.
4994
  ///
4995
  OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
4996
                                             SourceLocation EndLoc,
4997
                                             unsigned CollapsedNum)
4998
      : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4999
                         llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5000
                         StartLoc, EndLoc, CollapsedNum) {}
5001
 
5002
  /// Build an empty directive.
5003
  ///
5004
  /// \param CollapsedNum Number of collapsed nested loops.
5005
  ///
5006
  explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5007
      : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5008
                         llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5009
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5010
 
5011
public:
5012
  /// Creates directive with a list of \a Clauses.
5013
  ///
5014
  /// \param C AST context.
5015
  /// \param StartLoc Starting location of the directive kind.
5016
  /// \param EndLoc Ending Location of the directive.
5017
  /// \param CollapsedNum Number of collapsed loops.
5018
  /// \param Clauses List of clauses.
5019
  /// \param AssociatedStmt Statement, associated with the directive.
5020
  /// \param Exprs Helper expressions for CodeGen.
5021
  ///
5022
  static OMPTeamsDistributeParallelForSimdDirective *
5023
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5024
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5025
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
5026
 
5027
  /// Creates an empty directive with the place for \a NumClauses clauses.
5028
  ///
5029
  /// \param C AST context.
5030
  /// \param CollapsedNum Number of collapsed nested loops.
5031
  /// \param NumClauses Number of clauses.
5032
  ///
5033
  static OMPTeamsDistributeParallelForSimdDirective *
5034
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5035
              EmptyShell);
5036
 
5037
  static bool classof(const Stmt *T) {
5038
    return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
5039
  }
5040
};
5041
 
5042
/// This represents '#pragma omp teams distribute parallel for' composite
5043
/// directive.
5044
///
5045
/// \code
5046
/// #pragma omp teams distribute parallel for private(x)
5047
/// \endcode
5048
/// In this example directive '#pragma omp teams distribute parallel for'
5049
/// has clause 'private' with the variables 'x'
5050
///
5051
class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
5052
  friend class ASTStmtReader;
5053
  friend class OMPExecutableDirective;
5054
  /// true if the construct has inner cancel directive.
5055
  bool HasCancel = false;
5056
 
5057
  /// Build directive with the given start and end location.
5058
  ///
5059
  /// \param StartLoc Starting location of the directive kind.
5060
  /// \param EndLoc Ending location of the directive.
5061
  /// \param CollapsedNum Number of collapsed nested loops.
5062
  ///
5063
  OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5064
                                         SourceLocation EndLoc,
5065
                                         unsigned CollapsedNum)
5066
      : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5067
                         llvm::omp::OMPD_teams_distribute_parallel_for,
5068
                         StartLoc, EndLoc, CollapsedNum) {}
5069
 
5070
  /// Build an empty directive.
5071
  ///
5072
  /// \param CollapsedNum Number of collapsed nested loops.
5073
  ///
5074
  explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5075
      : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5076
                         llvm::omp::OMPD_teams_distribute_parallel_for,
5077
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5078
 
5079
  /// Sets special task reduction descriptor.
5080
  void setTaskReductionRefExpr(Expr *E) {
5081
    Data->getChildren()[numLoopChildren(
5082
        getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5083
  }
5084
 
5085
  /// Set cancel state.
5086
  void setHasCancel(bool Has) { HasCancel = Has; }
5087
 
5088
public:
5089
  /// Creates directive with a list of \a Clauses.
5090
  ///
5091
  /// \param C AST context.
5092
  /// \param StartLoc Starting location of the directive kind.
5093
  /// \param EndLoc Ending Location of the directive.
5094
  /// \param CollapsedNum Number of collapsed loops.
5095
  /// \param Clauses List of clauses.
5096
  /// \param AssociatedStmt Statement, associated with the directive.
5097
  /// \param Exprs Helper expressions for CodeGen.
5098
  /// \param TaskRedRef Task reduction special reference expression to handle
5099
  /// taskgroup descriptor.
5100
  /// \param HasCancel true if this directive has inner cancel directive.
5101
  ///
5102
  static OMPTeamsDistributeParallelForDirective *
5103
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5104
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5105
         Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5106
         bool HasCancel);
5107
 
5108
  /// Creates an empty directive with the place for \a NumClauses clauses.
5109
  ///
5110
  /// \param C AST context.
5111
  /// \param CollapsedNum Number of collapsed nested loops.
5112
  /// \param NumClauses Number of clauses.
5113
  ///
5114
  static OMPTeamsDistributeParallelForDirective *
5115
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5116
              EmptyShell);
5117
 
5118
  /// Returns special task reduction reference expression.
5119
  Expr *getTaskReductionRefExpr() {
5120
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5121
        getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5122
  }
5123
  const Expr *getTaskReductionRefExpr() const {
5124
    return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5125
        ->getTaskReductionRefExpr();
5126
  }
5127
 
5128
  /// Return true if current directive has inner cancel directive.
5129
  bool hasCancel() const { return HasCancel; }
5130
 
5131
  static bool classof(const Stmt *T) {
5132
    return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
5133
  }
5134
};
5135
 
5136
/// This represents '#pragma omp target teams' directive.
5137
///
5138
/// \code
5139
/// #pragma omp target teams if(a>0)
5140
/// \endcode
5141
/// In this example directive '#pragma omp target teams' has clause 'if' with
5142
/// condition 'a>0'.
5143
///
5144
class OMPTargetTeamsDirective final : public OMPExecutableDirective {
5145
  friend class ASTStmtReader;
5146
  friend class OMPExecutableDirective;
5147
  /// Build directive with the given start and end location.
5148
  ///
5149
  /// \param StartLoc Starting location of the directive kind.
5150
  /// \param EndLoc Ending location of the directive.
5151
  ///
5152
  OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5153
      : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5154
                               llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
5155
  }
5156
 
5157
  /// Build an empty directive.
5158
  ///
5159
  explicit OMPTargetTeamsDirective()
5160
      : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5161
                               llvm::omp::OMPD_target_teams, SourceLocation(),
5162
                               SourceLocation()) {}
5163
 
5164
public:
5165
  /// Creates directive with a list of \a Clauses.
5166
  ///
5167
  /// \param C AST context.
5168
  /// \param StartLoc Starting location of the directive kind.
5169
  /// \param EndLoc Ending Location of the directive.
5170
  /// \param Clauses List of clauses.
5171
  /// \param AssociatedStmt Statement, associated with the directive.
5172
  ///
5173
  static OMPTargetTeamsDirective *Create(const ASTContext &C,
5174
                                         SourceLocation StartLoc,
5175
                                         SourceLocation EndLoc,
5176
                                         ArrayRef<OMPClause *> Clauses,
5177
                                         Stmt *AssociatedStmt);
5178
 
5179
  /// Creates an empty directive with the place for \a NumClauses clauses.
5180
  ///
5181
  /// \param C AST context.
5182
  /// \param NumClauses Number of clauses.
5183
  ///
5184
  static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
5185
                                              unsigned NumClauses, EmptyShell);
5186
 
5187
  static bool classof(const Stmt *T) {
5188
    return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
5189
  }
5190
};
5191
 
5192
/// This represents '#pragma omp target teams distribute' combined directive.
5193
///
5194
/// \code
5195
/// #pragma omp target teams distribute private(x)
5196
/// \endcode
5197
/// In this example directive '#pragma omp target teams distribute' has clause
5198
/// 'private' with the variables 'x'
5199
///
5200
class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
5201
  friend class ASTStmtReader;
5202
  friend class OMPExecutableDirective;
5203
 
5204
  /// Build directive with the given start and end location.
5205
  ///
5206
  /// \param StartLoc Starting location of the directive kind.
5207
  /// \param EndLoc Ending location of the directive.
5208
  /// \param CollapsedNum Number of collapsed nested loops.
5209
  ///
5210
  OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
5211
                                    SourceLocation EndLoc,
5212
                                    unsigned CollapsedNum)
5213
      : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5214
                         llvm::omp::OMPD_target_teams_distribute, StartLoc,
5215
                         EndLoc, CollapsedNum) {}
5216
 
5217
  /// Build an empty directive.
5218
  ///
5219
  /// \param CollapsedNum Number of collapsed nested loops.
5220
  ///
5221
  explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
5222
      : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5223
                         llvm::omp::OMPD_target_teams_distribute,
5224
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5225
 
5226
public:
5227
  /// Creates directive with a list of \a Clauses.
5228
  ///
5229
  /// \param C AST context.
5230
  /// \param StartLoc Starting location of the directive kind.
5231
  /// \param EndLoc Ending Location of the directive.
5232
  /// \param CollapsedNum Number of collapsed loops.
5233
  /// \param Clauses List of clauses.
5234
  /// \param AssociatedStmt Statement, associated with the directive.
5235
  /// \param Exprs Helper expressions for CodeGen.
5236
  ///
5237
  static OMPTargetTeamsDistributeDirective *
5238
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5239
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5240
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
5241
 
5242
  /// Creates an empty directive with the place for \a NumClauses clauses.
5243
  ///
5244
  /// \param C AST context.
5245
  /// \param CollapsedNum Number of collapsed nested loops.
5246
  /// \param NumClauses Number of clauses.
5247
  ///
5248
  static OMPTargetTeamsDistributeDirective *
5249
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5250
              EmptyShell);
5251
 
5252
  static bool classof(const Stmt *T) {
5253
    return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
5254
  }
5255
};
5256
 
5257
/// This represents '#pragma omp target teams distribute parallel for' combined
5258
/// directive.
5259
///
5260
/// \code
5261
/// #pragma omp target teams distribute parallel for private(x)
5262
/// \endcode
5263
/// In this example directive '#pragma omp target teams distribute parallel
5264
/// for' has clause 'private' with the variables 'x'
5265
///
5266
class OMPTargetTeamsDistributeParallelForDirective final
5267
    : public OMPLoopDirective {
5268
  friend class ASTStmtReader;
5269
  friend class OMPExecutableDirective;
5270
  /// true if the construct has inner cancel directive.
5271
  bool HasCancel = false;
5272
 
5273
  /// Build directive with the given start and end location.
5274
  ///
5275
  /// \param StartLoc Starting location of the directive kind.
5276
  /// \param EndLoc Ending location of the directive.
5277
  /// \param CollapsedNum Number of collapsed nested loops.
5278
  ///
5279
  OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5280
                                               SourceLocation EndLoc,
5281
                                               unsigned CollapsedNum)
5282
      : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5283
                         llvm::omp::OMPD_target_teams_distribute_parallel_for,
5284
                         StartLoc, EndLoc, CollapsedNum) {}
5285
 
5286
  /// Build an empty directive.
5287
  ///
5288
  /// \param CollapsedNum Number of collapsed nested loops.
5289
  ///
5290
  explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5291
      : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5292
                         llvm::omp::OMPD_target_teams_distribute_parallel_for,
5293
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5294
 
5295
  /// Sets special task reduction descriptor.
5296
  void setTaskReductionRefExpr(Expr *E) {
5297
    Data->getChildren()[numLoopChildren(
5298
        getLoopsNumber(),
5299
        llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
5300
  }
5301
 
5302
  /// Set cancel state.
5303
  void setHasCancel(bool Has) { HasCancel = Has; }
5304
 
5305
public:
5306
  /// Creates directive with a list of \a Clauses.
5307
  ///
5308
  /// \param C AST context.
5309
  /// \param StartLoc Starting location of the directive kind.
5310
  /// \param EndLoc Ending Location of the directive.
5311
  /// \param CollapsedNum Number of collapsed loops.
5312
  /// \param Clauses List of clauses.
5313
  /// \param AssociatedStmt Statement, associated with the directive.
5314
  /// \param Exprs Helper expressions for CodeGen.
5315
  /// \param TaskRedRef Task reduction special reference expression to handle
5316
  /// taskgroup descriptor.
5317
  /// \param HasCancel true if this directive has inner cancel directive.
5318
  ///
5319
  static OMPTargetTeamsDistributeParallelForDirective *
5320
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5321
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5322
         Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5323
         bool HasCancel);
5324
 
5325
  /// Creates an empty directive with the place for \a NumClauses clauses.
5326
  ///
5327
  /// \param C AST context.
5328
  /// \param CollapsedNum Number of collapsed nested loops.
5329
  /// \param NumClauses Number of clauses.
5330
  ///
5331
  static OMPTargetTeamsDistributeParallelForDirective *
5332
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5333
              EmptyShell);
5334
 
5335
  /// Returns special task reduction reference expression.
5336
  Expr *getTaskReductionRefExpr() {
5337
    return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5338
        getLoopsNumber(),
5339
        llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
5340
  }
5341
  const Expr *getTaskReductionRefExpr() const {
5342
    return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
5343
        ->getTaskReductionRefExpr();
5344
  }
5345
 
5346
  /// Return true if current directive has inner cancel directive.
5347
  bool hasCancel() const { return HasCancel; }
5348
 
5349
  static bool classof(const Stmt *T) {
5350
    return T->getStmtClass() ==
5351
           OMPTargetTeamsDistributeParallelForDirectiveClass;
5352
  }
5353
};
5354
 
5355
/// This represents '#pragma omp target teams distribute parallel for simd'
5356
/// combined directive.
5357
///
5358
/// \code
5359
/// #pragma omp target teams distribute parallel for simd private(x)
5360
/// \endcode
5361
/// In this example directive '#pragma omp target teams distribute parallel
5362
/// for simd' has clause 'private' with the variables 'x'
5363
///
5364
class OMPTargetTeamsDistributeParallelForSimdDirective final
5365
    : public OMPLoopDirective {
5366
  friend class ASTStmtReader;
5367
  friend class OMPExecutableDirective;
5368
 
5369
  /// Build directive with the given start and end location.
5370
  ///
5371
  /// \param StartLoc Starting location of the directive kind.
5372
  /// \param EndLoc Ending location of the directive.
5373
  /// \param CollapsedNum Number of collapsed nested loops.
5374
  ///
5375
  OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
5376
                                                   SourceLocation EndLoc,
5377
                                                   unsigned CollapsedNum)
5378
      : OMPLoopDirective(
5379
            OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5380
            llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
5381
            EndLoc, CollapsedNum) {}
5382
 
5383
  /// Build an empty directive.
5384
  ///
5385
  /// \param CollapsedNum Number of collapsed nested loops.
5386
  ///
5387
  explicit OMPTargetTeamsDistributeParallelForSimdDirective(
5388
      unsigned CollapsedNum)
5389
      : OMPLoopDirective(
5390
            OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5391
            llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
5392
            SourceLocation(), SourceLocation(), CollapsedNum) {}
5393
 
5394
public:
5395
  /// Creates directive with a list of \a Clauses.
5396
  ///
5397
  /// \param C AST context.
5398
  /// \param StartLoc Starting location of the directive kind.
5399
  /// \param EndLoc Ending Location of the directive.
5400
  /// \param CollapsedNum Number of collapsed loops.
5401
  /// \param Clauses List of clauses.
5402
  /// \param AssociatedStmt Statement, associated with the directive.
5403
  /// \param Exprs Helper expressions for CodeGen.
5404
  ///
5405
  static OMPTargetTeamsDistributeParallelForSimdDirective *
5406
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5407
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5408
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
5409
 
5410
  /// Creates an empty directive with the place for \a NumClauses clauses.
5411
  ///
5412
  /// \param C AST context.
5413
  /// \param CollapsedNum Number of collapsed nested loops.
5414
  /// \param NumClauses Number of clauses.
5415
  ///
5416
  static OMPTargetTeamsDistributeParallelForSimdDirective *
5417
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5418
              EmptyShell);
5419
 
5420
  static bool classof(const Stmt *T) {
5421
    return T->getStmtClass() ==
5422
           OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
5423
  }
5424
};
5425
 
5426
/// This represents '#pragma omp target teams distribute simd' combined
5427
/// directive.
5428
///
5429
/// \code
5430
/// #pragma omp target teams distribute simd private(x)
5431
/// \endcode
5432
/// In this example directive '#pragma omp target teams distribute simd'
5433
/// has clause 'private' with the variables 'x'
5434
///
5435
class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
5436
  friend class ASTStmtReader;
5437
  friend class OMPExecutableDirective;
5438
 
5439
  /// Build directive with the given start and end location.
5440
  ///
5441
  /// \param StartLoc Starting location of the directive kind.
5442
  /// \param EndLoc Ending location of the directive.
5443
  /// \param CollapsedNum Number of collapsed nested loops.
5444
  ///
5445
  OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
5446
                                        SourceLocation EndLoc,
5447
                                        unsigned CollapsedNum)
5448
      : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5449
                         llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
5450
                         EndLoc, CollapsedNum) {}
5451
 
5452
  /// Build an empty directive.
5453
  ///
5454
  /// \param CollapsedNum Number of collapsed nested loops.
5455
  ///
5456
  explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
5457
      : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5458
                         llvm::omp::OMPD_target_teams_distribute_simd,
5459
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5460
 
5461
public:
5462
  /// Creates directive with a list of \a Clauses.
5463
  ///
5464
  /// \param C AST context.
5465
  /// \param StartLoc Starting location of the directive kind.
5466
  /// \param EndLoc Ending Location of the directive.
5467
  /// \param CollapsedNum Number of collapsed loops.
5468
  /// \param Clauses List of clauses.
5469
  /// \param AssociatedStmt Statement, associated with the directive.
5470
  /// \param Exprs Helper expressions for CodeGen.
5471
  ///
5472
  static OMPTargetTeamsDistributeSimdDirective *
5473
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5474
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5475
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
5476
 
5477
  /// Creates an empty directive with the place for \a NumClauses clauses.
5478
  ///
5479
  /// \param C AST context.
5480
  /// \param CollapsedNum Number of collapsed nested loops.
5481
  /// \param NumClauses Number of clauses.
5482
  ///
5483
  static OMPTargetTeamsDistributeSimdDirective *
5484
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5485
              EmptyShell);
5486
 
5487
  static bool classof(const Stmt *T) {
5488
    return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
5489
  }
5490
};
5491
 
5492
/// This represents the '#pragma omp tile' loop transformation directive.
5493
class OMPTileDirective final : public OMPLoopTransformationDirective {
5494
  friend class ASTStmtReader;
5495
  friend class OMPExecutableDirective;
5496
 
5497
  /// Default list of offsets.
5498
  enum {
5499
    PreInitsOffset = 0,
5500
    TransformedStmtOffset,
5501
  };
5502
 
5503
  explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5504
                            unsigned NumLoops)
5505
      : OMPLoopTransformationDirective(OMPTileDirectiveClass,
5506
                                       llvm::omp::OMPD_tile, StartLoc, EndLoc,
5507
                                       NumLoops) {
5508
    setNumGeneratedLoops(3 * NumLoops);
5509
  }
5510
 
5511
  void setPreInits(Stmt *PreInits) {
5512
    Data->getChildren()[PreInitsOffset] = PreInits;
5513
  }
5514
 
5515
  void setTransformedStmt(Stmt *S) {
5516
    Data->getChildren()[TransformedStmtOffset] = S;
5517
  }
5518
 
5519
public:
5520
  /// Create a new AST node representation for '#pragma omp tile'.
5521
  ///
5522
  /// \param C         Context of the AST.
5523
  /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
5524
  /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
5525
  /// \param Clauses   The directive's clauses.
5526
  /// \param NumLoops  Number of associated loops (number of items in the
5527
  ///                  'sizes' clause).
5528
  /// \param AssociatedStmt The outermost associated loop.
5529
  /// \param TransformedStmt The loop nest after tiling, or nullptr in
5530
  ///                        dependent contexts.
5531
  /// \param PreInits Helper preinits statements for the loop nest.
5532
  static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5533
                                  SourceLocation EndLoc,
5534
                                  ArrayRef<OMPClause *> Clauses,
5535
                                  unsigned NumLoops, Stmt *AssociatedStmt,
5536
                                  Stmt *TransformedStmt, Stmt *PreInits);
5537
 
5538
  /// Build an empty '#pragma omp tile' AST node for deserialization.
5539
  ///
5540
  /// \param C          Context of the AST.
5541
  /// \param NumClauses Number of clauses to allocate.
5542
  /// \param NumLoops   Number of associated loops to allocate.
5543
  static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5544
                                       unsigned NumLoops);
5545
 
5546
  /// Gets/sets the associated loops after tiling.
5547
  ///
5548
  /// This is in de-sugared format stored as a CompoundStmt.
5549
  ///
5550
  /// \code
5551
  ///   for (...)
5552
  ///     ...
5553
  /// \endcode
5554
  ///
5555
  /// Note that if the generated loops a become associated loops of another
5556
  /// directive, they may need to be hoisted before them.
5557
  Stmt *getTransformedStmt() const {
5558
    return Data->getChildren()[TransformedStmtOffset];
5559
  }
5560
 
5561
  /// Return preinits statement.
5562
  Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5563
 
5564
  static bool classof(const Stmt *T) {
5565
    return T->getStmtClass() == OMPTileDirectiveClass;
5566
  }
5567
};
5568
 
5569
/// This represents the '#pragma omp unroll' loop transformation directive.
5570
///
5571
/// \code
5572
/// #pragma omp unroll
5573
/// for (int i = 0; i < 64; ++i)
5574
/// \endcode
5575
class OMPUnrollDirective final : public OMPLoopTransformationDirective {
5576
  friend class ASTStmtReader;
5577
  friend class OMPExecutableDirective;
5578
 
5579
  /// Default list of offsets.
5580
  enum {
5581
    PreInitsOffset = 0,
5582
    TransformedStmtOffset,
5583
  };
5584
 
5585
  explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5586
      : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
5587
                                       llvm::omp::OMPD_unroll, StartLoc, EndLoc,
5588
                                       1) {}
5589
 
5590
  /// Set the pre-init statements.
5591
  void setPreInits(Stmt *PreInits) {
5592
    Data->getChildren()[PreInitsOffset] = PreInits;
5593
  }
5594
 
5595
  /// Set the de-sugared statement.
5596
  void setTransformedStmt(Stmt *S) {
5597
    Data->getChildren()[TransformedStmtOffset] = S;
5598
  }
5599
 
5600
public:
5601
  /// Create a new AST node representation for '#pragma omp unroll'.
5602
  ///
5603
  /// \param C         Context of the AST.
5604
  /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
5605
  /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
5606
  /// \param Clauses   The directive's clauses.
5607
  /// \param AssociatedStmt The outermost associated loop.
5608
  /// \param TransformedStmt The loop nest after tiling, or nullptr in
5609
  ///                        dependent contexts.
5610
  /// \param PreInits   Helper preinits statements for the loop nest.
5611
  static OMPUnrollDirective *
5612
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5613
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5614
         unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
5615
 
5616
  /// Build an empty '#pragma omp unroll' AST node for deserialization.
5617
  ///
5618
  /// \param C          Context of the AST.
5619
  /// \param NumClauses Number of clauses to allocate.
5620
  static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
5621
                                         unsigned NumClauses);
5622
 
5623
  /// Get the de-sugared associated loops after unrolling.
5624
  ///
5625
  /// This is only used if the unrolled loop becomes an associated loop of
5626
  /// another directive, otherwise the loop is emitted directly using loop
5627
  /// transformation metadata. When the unrolled loop cannot be used by another
5628
  /// directive (e.g. because of the full clause), the transformed stmt can also
5629
  /// be nullptr.
5630
  Stmt *getTransformedStmt() const {
5631
    return Data->getChildren()[TransformedStmtOffset];
5632
  }
5633
 
5634
  /// Return the pre-init statements.
5635
  Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5636
 
5637
  static bool classof(const Stmt *T) {
5638
    return T->getStmtClass() == OMPUnrollDirectiveClass;
5639
  }
5640
};
5641
 
5642
/// This represents '#pragma omp scan' directive.
5643
///
5644
/// \code
5645
/// #pragma omp scan inclusive(a)
5646
/// \endcode
5647
/// In this example directive '#pragma omp scan' has clause 'inclusive' with
5648
/// list item 'a'.
5649
class OMPScanDirective final : public OMPExecutableDirective {
5650
  friend class ASTStmtReader;
5651
  friend class OMPExecutableDirective;
5652
  /// Build directive with the given start and end location.
5653
  ///
5654
  /// \param StartLoc Starting location of the directive kind.
5655
  /// \param EndLoc Ending location of the directive.
5656
  ///
5657
  OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5658
      : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5659
                               StartLoc, EndLoc) {}
5660
 
5661
  /// Build an empty directive.
5662
  ///
5663
  explicit OMPScanDirective()
5664
      : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5665
                               SourceLocation(), SourceLocation()) {}
5666
 
5667
public:
5668
  /// Creates directive with a list of \a Clauses.
5669
  ///
5670
  /// \param C AST context.
5671
  /// \param StartLoc Starting location of the directive kind.
5672
  /// \param EndLoc Ending Location of the directive.
5673
  /// \param Clauses List of clauses (only single OMPFlushClause clause is
5674
  /// allowed).
5675
  ///
5676
  static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5677
                                  SourceLocation EndLoc,
5678
                                  ArrayRef<OMPClause *> Clauses);
5679
 
5680
  /// Creates an empty directive with the place for \a NumClauses
5681
  /// clauses.
5682
  ///
5683
  /// \param C AST context.
5684
  /// \param NumClauses Number of clauses.
5685
  ///
5686
  static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5687
                                       EmptyShell);
5688
 
5689
  static bool classof(const Stmt *T) {
5690
    return T->getStmtClass() == OMPScanDirectiveClass;
5691
  }
5692
};
5693
 
5694
/// This represents '#pragma omp interop' directive.
5695
///
5696
/// \code
5697
/// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
5698
/// \endcode
5699
/// In this example directive '#pragma omp interop' has
5700
/// clauses 'init', 'device', 'depend' and 'nowait'.
5701
///
5702
class OMPInteropDirective final : public OMPExecutableDirective {
5703
  friend class ASTStmtReader;
5704
  friend class OMPExecutableDirective;
5705
 
5706
  /// Build directive with the given start and end location.
5707
  ///
5708
  /// \param StartLoc Starting location of the directive.
5709
  /// \param EndLoc Ending location of the directive.
5710
  ///
5711
  OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5712
      : OMPExecutableDirective(OMPInteropDirectiveClass,
5713
                               llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
5714
 
5715
  /// Build an empty directive.
5716
  ///
5717
  explicit OMPInteropDirective()
5718
      : OMPExecutableDirective(OMPInteropDirectiveClass,
5719
                               llvm::omp::OMPD_interop, SourceLocation(),
5720
                               SourceLocation()) {}
5721
 
5722
public:
5723
  /// Creates directive.
5724
  ///
5725
  /// \param C AST context.
5726
  /// \param StartLoc Starting location of the directive.
5727
  /// \param EndLoc Ending Location of the directive.
5728
  /// \param Clauses The directive's clauses.
5729
  ///
5730
  static OMPInteropDirective *Create(const ASTContext &C,
5731
                                     SourceLocation StartLoc,
5732
                                     SourceLocation EndLoc,
5733
                                     ArrayRef<OMPClause *> Clauses);
5734
 
5735
  /// Creates an empty directive.
5736
  ///
5737
  /// \param C AST context.
5738
  ///
5739
  static OMPInteropDirective *CreateEmpty(const ASTContext &C,
5740
                                          unsigned NumClauses, EmptyShell);
5741
 
5742
  static bool classof(const Stmt *T) {
5743
    return T->getStmtClass() == OMPInteropDirectiveClass;
5744
  }
5745
};
5746
 
5747
/// This represents '#pragma omp dispatch' directive.
5748
///
5749
/// \code
5750
/// #pragma omp dispatch device(dnum)
5751
/// \endcode
5752
/// This example shows a directive '#pragma omp dispatch' with a
5753
/// device clause with variable 'dnum'.
5754
///
5755
class OMPDispatchDirective final : public OMPExecutableDirective {
5756
  friend class ASTStmtReader;
5757
  friend class OMPExecutableDirective;
5758
 
5759
  /// The location of the target-call.
5760
  SourceLocation TargetCallLoc;
5761
 
5762
  /// Set the location of the target-call.
5763
  void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
5764
 
5765
  /// Build directive with the given start and end location.
5766
  ///
5767
  /// \param StartLoc Starting location of the directive kind.
5768
  /// \param EndLoc Ending location of the directive.
5769
  ///
5770
  OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5771
      : OMPExecutableDirective(OMPDispatchDirectiveClass,
5772
                               llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
5773
 
5774
  /// Build an empty directive.
5775
  ///
5776
  explicit OMPDispatchDirective()
5777
      : OMPExecutableDirective(OMPDispatchDirectiveClass,
5778
                               llvm::omp::OMPD_dispatch, SourceLocation(),
5779
                               SourceLocation()) {}
5780
 
5781
public:
5782
  /// Creates directive with a list of \a Clauses.
5783
  ///
5784
  /// \param C AST context.
5785
  /// \param StartLoc Starting location of the directive kind.
5786
  /// \param EndLoc Ending Location of the directive.
5787
  /// \param Clauses List of clauses.
5788
  /// \param AssociatedStmt Statement, associated with the directive.
5789
  /// \param TargetCallLoc Location of the target-call.
5790
  ///
5791
  static OMPDispatchDirective *
5792
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5793
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5794
         SourceLocation TargetCallLoc);
5795
 
5796
  /// Creates an empty directive with the place for \a NumClauses
5797
  /// clauses.
5798
  ///
5799
  /// \param C AST context.
5800
  /// \param NumClauses Number of clauses.
5801
  ///
5802
  static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
5803
                                           unsigned NumClauses, EmptyShell);
5804
 
5805
  /// Return location of target-call.
5806
  SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
5807
 
5808
  static bool classof(const Stmt *T) {
5809
    return T->getStmtClass() == OMPDispatchDirectiveClass;
5810
  }
5811
};
5812
 
5813
/// This represents '#pragma omp masked' directive.
5814
/// \code
5815
/// #pragma omp masked filter(tid)
5816
/// \endcode
5817
/// This example shows a directive '#pragma omp masked' with a filter clause
5818
/// with variable 'tid'.
5819
///
5820
class OMPMaskedDirective final : public OMPExecutableDirective {
5821
  friend class ASTStmtReader;
5822
  friend class OMPExecutableDirective;
5823
 
5824
  /// Build directive with the given start and end location.
5825
  ///
5826
  /// \param StartLoc Starting location of the directive kind.
5827
  /// \param EndLoc Ending location of the directive.
5828
  ///
5829
  OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5830
      : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5831
                               StartLoc, EndLoc) {}
5832
 
5833
  /// Build an empty directive.
5834
  ///
5835
  explicit OMPMaskedDirective()
5836
      : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5837
                               SourceLocation(), SourceLocation()) {}
5838
 
5839
public:
5840
  /// Creates directive.
5841
  ///
5842
  /// \param C AST context.
5843
  /// \param StartLoc Starting location of the directive kind.
5844
  /// \param EndLoc Ending Location of the directive.
5845
  /// \param AssociatedStmt Statement, associated with the directive.
5846
  ///
5847
  static OMPMaskedDirective *
5848
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5849
         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
5850
 
5851
  /// Creates an empty directive.
5852
  ///
5853
  /// \param C AST context.
5854
  ///
5855
  static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
5856
                                         unsigned NumClauses, EmptyShell);
5857
 
5858
  static bool classof(const Stmt *T) {
5859
    return T->getStmtClass() == OMPMaskedDirectiveClass;
5860
  }
5861
};
5862
 
5863
/// This represents '#pragma omp metadirective' directive.
5864
///
5865
/// \code
5866
/// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
5867
/// \endcode
5868
/// In this example directive '#pragma omp metadirective' has clauses 'when'
5869
/// with a dynamic user condition to check if a variable 'N > 10'
5870
///
5871
class OMPMetaDirective final : public OMPExecutableDirective {
5872
  friend class ASTStmtReader;
5873
  friend class OMPExecutableDirective;
5874
  Stmt *IfStmt;
5875
 
5876
  OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5877
      : OMPExecutableDirective(OMPMetaDirectiveClass,
5878
                               llvm::omp::OMPD_metadirective, StartLoc,
5879
                               EndLoc) {}
5880
  explicit OMPMetaDirective()
5881
      : OMPExecutableDirective(OMPMetaDirectiveClass,
5882
                               llvm::omp::OMPD_metadirective, SourceLocation(),
5883
                               SourceLocation()) {}
5884
 
5885
  void setIfStmt(Stmt *S) { IfStmt = S; }
5886
 
5887
public:
5888
  static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5889
                                  SourceLocation EndLoc,
5890
                                  ArrayRef<OMPClause *> Clauses,
5891
                                  Stmt *AssociatedStmt, Stmt *IfStmt);
5892
  static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5893
                                       EmptyShell);
5894
  Stmt *getIfStmt() const { return IfStmt; }
5895
 
5896
  static bool classof(const Stmt *T) {
5897
    return T->getStmtClass() == OMPMetaDirectiveClass;
5898
  }
5899
};
5900
 
5901
/// This represents '#pragma omp loop' directive.
5902
///
5903
/// \code
5904
/// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
5905
/// \endcode
5906
/// In this example directive '#pragma omp loop' has
5907
/// clauses 'private' with the variables 'a' and 'b', 'binding' with
5908
/// modifier 'parallel' and 'order(concurrent).
5909
///
5910
class OMPGenericLoopDirective final : public OMPLoopDirective {
5911
  friend class ASTStmtReader;
5912
  friend class OMPExecutableDirective;
5913
  /// Build directive with the given start and end location.
5914
  ///
5915
  /// \param StartLoc Starting location of the directive kind.
5916
  /// \param EndLoc Ending location of the directive.
5917
  /// \param CollapsedNum Number of collapsed nested loops.
5918
  ///
5919
  OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5920
                          unsigned CollapsedNum)
5921
      : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5922
                         StartLoc, EndLoc, CollapsedNum) {}
5923
 
5924
  /// Build an empty directive.
5925
  ///
5926
  /// \param CollapsedNum Number of collapsed nested loops.
5927
  ///
5928
  explicit OMPGenericLoopDirective(unsigned CollapsedNum)
5929
      : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5930
                         SourceLocation(), SourceLocation(), CollapsedNum) {}
5931
 
5932
public:
5933
  /// Creates directive with a list of \p Clauses.
5934
  ///
5935
  /// \param C AST context.
5936
  /// \param StartLoc Starting location of the directive kind.
5937
  /// \param EndLoc Ending Location of the directive.
5938
  /// \param CollapsedNum Number of collapsed loops.
5939
  /// \param Clauses List of clauses.
5940
  /// \param AssociatedStmt Statement, associated with the directive.
5941
  /// \param Exprs Helper expressions for CodeGen.
5942
  ///
5943
  static OMPGenericLoopDirective *
5944
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5945
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5946
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
5947
 
5948
  /// Creates an empty directive with a place for \a NumClauses clauses.
5949
  ///
5950
  /// \param C AST context.
5951
  /// \param NumClauses Number of clauses.
5952
  /// \param CollapsedNum Number of collapsed nested loops.
5953
  ///
5954
  static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
5955
                                              unsigned NumClauses,
5956
                                              unsigned CollapsedNum,
5957
                                              EmptyShell);
5958
 
5959
  static bool classof(const Stmt *T) {
5960
    return T->getStmtClass() == OMPGenericLoopDirectiveClass;
5961
  }
5962
};
5963
 
5964
/// This represents '#pragma omp teams loop' directive.
5965
///
5966
/// \code
5967
/// #pragma omp teams loop private(a,b) order(concurrent)
5968
/// \endcode
5969
/// In this example directive '#pragma omp teams loop' has
5970
/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
5971
///
5972
class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
5973
  friend class ASTStmtReader;
5974
  friend class OMPExecutableDirective;
5975
  /// Build directive with the given start and end location.
5976
  ///
5977
  /// \param StartLoc Starting location of the directive kind.
5978
  /// \param EndLoc Ending location of the directive.
5979
  /// \param CollapsedNum Number of collapsed nested loops.
5980
  ///
5981
  OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5982
                               unsigned CollapsedNum)
5983
      : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
5984
                         llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
5985
                         CollapsedNum) {}
5986
 
5987
  /// Build an empty directive.
5988
  ///
5989
  /// \param CollapsedNum Number of collapsed nested loops.
5990
  ///
5991
  explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
5992
      : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
5993
                         llvm::omp::OMPD_teams_loop, SourceLocation(),
5994
                         SourceLocation(), CollapsedNum) {}
5995
 
5996
public:
5997
  /// Creates directive with a list of \p Clauses.
5998
  ///
5999
  /// \param C AST context.
6000
  /// \param StartLoc Starting location of the directive kind.
6001
  /// \param EndLoc Ending Location of the directive.
6002
  /// \param CollapsedNum Number of collapsed loops.
6003
  /// \param Clauses List of clauses.
6004
  /// \param AssociatedStmt Statement, associated with the directive.
6005
  /// \param Exprs Helper expressions for CodeGen.
6006
  ///
6007
  static OMPTeamsGenericLoopDirective *
6008
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6009
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6010
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
6011
 
6012
  /// Creates an empty directive with the place
6013
  /// for \a NumClauses clauses.
6014
  ///
6015
  /// \param C AST context.
6016
  /// \param CollapsedNum Number of collapsed nested loops.
6017
  /// \param NumClauses Number of clauses.
6018
  ///
6019
  static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6020
                                                   unsigned NumClauses,
6021
                                                   unsigned CollapsedNum,
6022
                                                   EmptyShell);
6023
 
6024
  static bool classof(const Stmt *T) {
6025
    return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
6026
  }
6027
};
6028
 
6029
/// This represents '#pragma omp target teams loop' directive.
6030
///
6031
/// \code
6032
/// #pragma omp target teams loop private(a,b) order(concurrent)
6033
/// \endcode
6034
/// In this example directive '#pragma omp target teams loop' has
6035
/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6036
///
6037
class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
6038
  friend class ASTStmtReader;
6039
  friend class OMPExecutableDirective;
6040
  /// Build directive with the given start and end location.
6041
  ///
6042
  /// \param StartLoc Starting location of the directive kind.
6043
  /// \param EndLoc Ending location of the directive.
6044
  /// \param CollapsedNum Number of collapsed nested loops.
6045
  ///
6046
  OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
6047
                                     SourceLocation EndLoc,
6048
                                     unsigned CollapsedNum)
6049
      : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6050
                         llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
6051
                         CollapsedNum) {}
6052
 
6053
  /// Build an empty directive.
6054
  ///
6055
  /// \param CollapsedNum Number of collapsed nested loops.
6056
  ///
6057
  explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
6058
      : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6059
                         llvm::omp::OMPD_target_teams_loop, SourceLocation(),
6060
                         SourceLocation(), CollapsedNum) {}
6061
 
6062
public:
6063
  /// Creates directive with a list of \p Clauses.
6064
  ///
6065
  /// \param C AST context.
6066
  /// \param StartLoc Starting location of the directive kind.
6067
  /// \param EndLoc Ending Location of the directive.
6068
  /// \param CollapsedNum Number of collapsed loops.
6069
  /// \param Clauses List of clauses.
6070
  /// \param AssociatedStmt Statement, associated with the directive.
6071
  /// \param Exprs Helper expressions for CodeGen.
6072
  ///
6073
  static OMPTargetTeamsGenericLoopDirective *
6074
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6075
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6076
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
6077
 
6078
  /// Creates an empty directive with the place
6079
  /// for \a NumClauses clauses.
6080
  ///
6081
  /// \param C AST context.
6082
  /// \param CollapsedNum Number of collapsed nested loops.
6083
  /// \param NumClauses Number of clauses.
6084
  ///
6085
  static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6086
                                                         unsigned NumClauses,
6087
                                                         unsigned CollapsedNum,
6088
                                                         EmptyShell);
6089
 
6090
  static bool classof(const Stmt *T) {
6091
    return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
6092
  }
6093
};
6094
 
6095
/// This represents '#pragma omp parallel loop' directive.
6096
///
6097
/// \code
6098
/// #pragma omp parallel loop private(a,b) order(concurrent)
6099
/// \endcode
6100
/// In this example directive '#pragma omp parallel loop' has
6101
/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6102
///
6103
class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
6104
  friend class ASTStmtReader;
6105
  friend class OMPExecutableDirective;
6106
  /// Build directive with the given start and end location.
6107
  ///
6108
  /// \param StartLoc Starting location of the directive kind.
6109
  /// \param EndLoc Ending location of the directive.
6110
  /// \param CollapsedNum Number of collapsed nested loops.
6111
  ///
6112
  OMPParallelGenericLoopDirective(SourceLocation StartLoc,
6113
                                  SourceLocation EndLoc, unsigned CollapsedNum)
6114
      : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6115
                         llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
6116
                         CollapsedNum) {}
6117
 
6118
  /// Build an empty directive.
6119
  ///
6120
  /// \param CollapsedNum Number of collapsed nested loops.
6121
  ///
6122
  explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
6123
      : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6124
                         llvm::omp::OMPD_parallel_loop, SourceLocation(),
6125
                         SourceLocation(), CollapsedNum) {}
6126
 
6127
public:
6128
  /// Creates directive with a list of \p Clauses.
6129
  ///
6130
  /// \param C AST context.
6131
  /// \param StartLoc Starting location of the directive kind.
6132
  /// \param EndLoc Ending Location of the directive.
6133
  /// \param CollapsedNum Number of collapsed loops.
6134
  /// \param Clauses List of clauses.
6135
  /// \param AssociatedStmt Statement, associated with the directive.
6136
  /// \param Exprs Helper expressions for CodeGen.
6137
  ///
6138
  static OMPParallelGenericLoopDirective *
6139
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6140
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6141
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
6142
 
6143
  /// Creates an empty directive with the place
6144
  /// for \a NumClauses clauses.
6145
  ///
6146
  /// \param C AST context.
6147
  /// \param CollapsedNum Number of collapsed nested loops.
6148
  /// \param NumClauses Number of clauses.
6149
  ///
6150
  static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
6151
                                                      unsigned NumClauses,
6152
                                                      unsigned CollapsedNum,
6153
                                                      EmptyShell);
6154
 
6155
  static bool classof(const Stmt *T) {
6156
    return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
6157
  }
6158
};
6159
 
6160
/// This represents '#pragma omp target parallel loop' directive.
6161
///
6162
/// \code
6163
/// #pragma omp target parallel loop private(a,b) order(concurrent)
6164
/// \endcode
6165
/// In this example directive '#pragma omp target parallel loop' has
6166
/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6167
///
6168
class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
6169
  friend class ASTStmtReader;
6170
  friend class OMPExecutableDirective;
6171
  /// Build directive with the given start and end location.
6172
  ///
6173
  /// \param StartLoc Starting location of the directive kind.
6174
  /// \param EndLoc Ending location of the directive.
6175
  /// \param CollapsedNum Number of collapsed nested loops.
6176
  ///
6177
  OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
6178
                                        SourceLocation EndLoc,
6179
                                        unsigned CollapsedNum)
6180
      : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6181
                         llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
6182
                         CollapsedNum) {}
6183
 
6184
  /// Build an empty directive.
6185
  ///
6186
  /// \param CollapsedNum Number of collapsed nested loops.
6187
  ///
6188
  explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
6189
      : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6190
                         llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
6191
                         SourceLocation(), CollapsedNum) {}
6192
 
6193
public:
6194
  /// Creates directive with a list of \p Clauses.
6195
  ///
6196
  /// \param C AST context.
6197
  /// \param StartLoc Starting location of the directive kind.
6198
  /// \param EndLoc Ending Location of the directive.
6199
  /// \param CollapsedNum Number of collapsed loops.
6200
  /// \param Clauses List of clauses.
6201
  /// \param AssociatedStmt Statement, associated with the directive.
6202
  /// \param Exprs Helper expressions for CodeGen.
6203
  ///
6204
  static OMPTargetParallelGenericLoopDirective *
6205
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6206
         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6207
         Stmt *AssociatedStmt, const HelperExprs &Exprs);
6208
 
6209
  /// Creates an empty directive with the place
6210
  /// for \a NumClauses clauses.
6211
  ///
6212
  /// \param C AST context.
6213
  /// \param CollapsedNum Number of collapsed nested loops.
6214
  /// \param NumClauses Number of clauses.
6215
  ///
6216
  static OMPTargetParallelGenericLoopDirective *
6217
  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
6218
              EmptyShell);
6219
 
6220
  static bool classof(const Stmt *T) {
6221
    return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
6222
  }
6223
};
6224
 
6225
/// This represents '#pragma omp error' directive.
6226
///
6227
/// \code
6228
/// #pragma omp error
6229
/// \endcode
6230
class OMPErrorDirective final : public OMPExecutableDirective {
6231
  friend class ASTStmtReader;
6232
  friend class OMPExecutableDirective;
6233
  /// Build directive with the given start and end location.
6234
  ///
6235
  /// \param StartLoc Starting location of the directive kind.
6236
  /// \param EndLoc Ending location of the directive.
6237
  ///
6238
  OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6239
      : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6240
                               StartLoc, EndLoc) {}
6241
  /// Build an empty directive.
6242
  ///
6243
  explicit OMPErrorDirective()
6244
      : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6245
                               SourceLocation(), SourceLocation()) {}
6246
 
6247
public:
6248
  ///
6249
  /// \param C AST context.
6250
  /// \param StartLoc Starting location of the directive kind.
6251
  /// \param EndLoc Ending Location of the directive.
6252
  /// \param Clauses List of clauses.
6253
  ///
6254
  static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6255
                                   SourceLocation EndLoc,
6256
                                   ArrayRef<OMPClause *> Clauses);
6257
 
6258
  /// Creates an empty directive.
6259
  ///
6260
  /// \param C AST context.
6261
  ///
6262
  static OMPErrorDirective *CreateEmpty(const ASTContext &C,
6263
                                        unsigned NumClauses, EmptyShell);
6264
 
6265
  static bool classof(const Stmt *T) {
6266
    return T->getStmtClass() == OMPErrorDirectiveClass;
6267
  }
6268
};
6269
} // end namespace clang
6270
 
6271
#endif