Home | History | Annotate | Download | only in AST
      1 //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file defines OpenMP AST classes for executable directives and
     11 /// clauses.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
     16 #define LLVM_CLANG_AST_STMTOPENMP_H
     17 
     18 #include "clang/AST/Expr.h"
     19 #include "clang/AST/OpenMPClause.h"
     20 #include "clang/AST/Stmt.h"
     21 #include "clang/Basic/OpenMPKinds.h"
     22 #include "clang/Basic/SourceLocation.h"
     23 
     24 namespace clang {
     25 
     26 //===----------------------------------------------------------------------===//
     27 // AST classes for directives.
     28 //===----------------------------------------------------------------------===//
     29 
     30 /// \brief This is a basic class for representing single OpenMP executable
     31 /// directive.
     32 ///
     33 class OMPExecutableDirective : public Stmt {
     34   friend class ASTStmtReader;
     35   /// \brief Kind of the directive.
     36   OpenMPDirectiveKind Kind;
     37   /// \brief Starting location of the directive (directive keyword).
     38   SourceLocation StartLoc;
     39   /// \brief Ending location of the directive.
     40   SourceLocation EndLoc;
     41   /// \brief Numbers of clauses.
     42   const unsigned NumClauses;
     43   /// \brief Number of child expressions/stmts.
     44   const unsigned NumChildren;
     45   /// \brief Offset from this to the start of clauses.
     46   /// There are NumClauses pointers to clauses, they are followed by
     47   /// NumChildren pointers to child stmts/exprs (if the directive type
     48   /// requires an associated stmt, then it has to be the first of them).
     49   const unsigned ClausesOffset;
     50 
     51   /// \brief Get the clauses storage.
     52   MutableArrayRef<OMPClause *> getClauses() {
     53     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
     54         reinterpret_cast<char *>(this) + ClausesOffset);
     55     return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
     56   }
     57 
     58 protected:
     59   /// \brief Build instance of directive of class \a K.
     60   ///
     61   /// \param SC Statement class.
     62   /// \param K Kind of OpenMP directive.
     63   /// \param StartLoc Starting location of the directive (directive keyword).
     64   /// \param EndLoc Ending location of the directive.
     65   ///
     66   template <typename T>
     67   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
     68                          SourceLocation StartLoc, SourceLocation EndLoc,
     69                          unsigned NumClauses, unsigned NumChildren)
     70       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
     71         EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
     72         NumChildren(NumChildren),
     73         ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
     74                                                llvm::alignOf<OMPClause *>())) {}
     75 
     76   /// \brief Sets the list of variables for this clause.
     77   ///
     78   /// \param Clauses The list of clauses for the directive.
     79   ///
     80   void setClauses(ArrayRef<OMPClause *> Clauses);
     81 
     82   /// \brief Set the associated statement for the directive.
     83   ///
     84   /// /param S Associated statement.
     85   ///
     86   void setAssociatedStmt(Stmt *S) { *child_begin() = S; }
     87 
     88 public:
     89   /// \brief Iterates over a filtered subrange of clauses applied to a
     90   /// directive.
     91   ///
     92   /// This iterator visits only those declarations that meet some run-time
     93   /// criteria.
     94   template <class FilterPredicate> class filtered_clause_iterator {
     95     ArrayRef<OMPClause *>::const_iterator Current;
     96     ArrayRef<OMPClause *>::const_iterator End;
     97     FilterPredicate Pred;
     98     void SkipToNextClause() {
     99       while (Current != End && !Pred(*Current))
    100         ++Current;
    101     }
    102 
    103   public:
    104     typedef const OMPClause *value_type;
    105     filtered_clause_iterator() : Current(), End() {}
    106     filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
    107         : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
    108       SkipToNextClause();
    109     }
    110     value_type operator*() const { return *Current; }
    111     value_type operator->() const { return *Current; }
    112     filtered_clause_iterator &operator++() {
    113       ++Current;
    114       SkipToNextClause();
    115       return *this;
    116     }
    117 
    118     filtered_clause_iterator operator++(int) {
    119       filtered_clause_iterator tmp(*this);
    120       ++(*this);
    121       return tmp;
    122     }
    123 
    124     bool operator!() { return Current == End; }
    125     operator bool() { return Current != End; }
    126   };
    127 
    128   /// \brief Returns starting location of directive kind.
    129   SourceLocation getLocStart() const { return StartLoc; }
    130   /// \brief Returns ending location of directive.
    131   SourceLocation getLocEnd() const { return EndLoc; }
    132 
    133   /// \brief Set starting location of directive kind.
    134   ///
    135   /// \param Loc New starting location of directive.
    136   ///
    137   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    138   /// \brief Set ending location of directive.
    139   ///
    140   /// \param Loc New ending location of directive.
    141   ///
    142   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    143 
    144   /// \brief Get number of clauses.
    145   unsigned getNumClauses() const { return NumClauses; }
    146 
    147   /// \brief Returns specified clause.
    148   ///
    149   /// \param i Number of clause.
    150   ///
    151   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
    152 
    153   /// \brief Returns statement associated with the directive.
    154   Stmt *getAssociatedStmt() const { return const_cast<Stmt *>(*child_begin()); }
    155 
    156   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    157 
    158   static bool classof(const Stmt *S) {
    159     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    160            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    161   }
    162 
    163   child_range children() {
    164     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
    165     return child_range(ChildStorage, ChildStorage + NumChildren);
    166   }
    167 
    168   ArrayRef<OMPClause *> clauses() { return getClauses(); }
    169 
    170   ArrayRef<OMPClause *> clauses() const {
    171     return const_cast<OMPExecutableDirective *>(this)->getClauses();
    172   }
    173 };
    174 
    175 /// \brief This represents '#pragma omp parallel' directive.
    176 ///
    177 /// \code
    178 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    179 /// \endcode
    180 /// In this example directive '#pragma omp parallel' has clauses 'private'
    181 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    182 /// variables 'c' and 'd'.
    183 ///
    184 class OMPParallelDirective : public OMPExecutableDirective {
    185   /// \brief Build directive with the given start and end location.
    186   ///
    187   /// \param StartLoc Starting location of the directive (directive keyword).
    188   /// \param EndLoc Ending Location of the directive.
    189   ///
    190   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    191                        unsigned NumClauses)
    192       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    193                                StartLoc, EndLoc, NumClauses, 1) {}
    194 
    195   /// \brief Build an empty directive.
    196   ///
    197   /// \param NumClauses Number of clauses.
    198   ///
    199   explicit OMPParallelDirective(unsigned NumClauses)
    200       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    201                                SourceLocation(), SourceLocation(), NumClauses,
    202                                1) {}
    203 
    204 public:
    205   /// \brief Creates directive with a list of \a Clauses.
    206   ///
    207   /// \param C AST context.
    208   /// \param StartLoc Starting location of the directive kind.
    209   /// \param EndLoc Ending Location of the directive.
    210   /// \param Clauses List of clauses.
    211   /// \param AssociatedStmt Statement associated with the directive.
    212   ///
    213   static OMPParallelDirective *
    214   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    215          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    216 
    217   /// \brief Creates an empty directive with the place for \a N clauses.
    218   ///
    219   /// \param C AST context.
    220   /// \param NumClauses Number of clauses.
    221   ///
    222   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
    223                                            unsigned NumClauses, EmptyShell);
    224 
    225   static bool classof(const Stmt *T) {
    226     return T->getStmtClass() == OMPParallelDirectiveClass;
    227   }
    228 };
    229 
    230 /// \brief This represents '#pragma omp simd' directive.
    231 ///
    232 /// \code
    233 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
    234 /// \endcode
    235 /// In this example directive '#pragma omp simd' has clauses 'private'
    236 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    237 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    238 ///
    239 class OMPSimdDirective : public OMPExecutableDirective {
    240   friend class ASTStmtReader;
    241   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    242   unsigned CollapsedNum;
    243   /// \brief Build directive with the given start and end location.
    244   ///
    245   /// \param StartLoc Starting location of the directive kind.
    246   /// \param EndLoc Ending location of the directive.
    247   /// \param CollapsedNum Number of collapsed nested loops.
    248   /// \param NumClauses Number of clauses.
    249   ///
    250   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    251                    unsigned CollapsedNum, unsigned NumClauses)
    252       : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
    253                                EndLoc, NumClauses, 1),
    254         CollapsedNum(CollapsedNum) {}
    255 
    256   /// \brief Build an empty directive.
    257   ///
    258   /// \param CollapsedNum Number of collapsed nested loops.
    259   /// \param NumClauses Number of clauses.
    260   ///
    261   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    262       : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
    263                                SourceLocation(), SourceLocation(), NumClauses,
    264                                1),
    265         CollapsedNum(CollapsedNum) {}
    266 
    267 public:
    268   /// \brief Creates directive with a list of \a Clauses.
    269   ///
    270   /// \param C AST context.
    271   /// \param StartLoc Starting location of the directive kind.
    272   /// \param EndLoc Ending Location of the directive.
    273   /// \param CollapsedNum Number of collapsed loops.
    274   /// \param Clauses List of clauses.
    275   /// \param AssociatedStmt Statement, associated with the directive.
    276   ///
    277   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    278                                   SourceLocation EndLoc, unsigned CollapsedNum,
    279                                   ArrayRef<OMPClause *> Clauses,
    280                                   Stmt *AssociatedStmt);
    281 
    282   /// \brief Creates an empty directive with the place
    283   /// for \a NumClauses clauses.
    284   ///
    285   /// \param C AST context.
    286   /// \param CollapsedNum Number of collapsed nested loops.
    287   /// \param NumClauses Number of clauses.
    288   ///
    289   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    290                                        unsigned CollapsedNum, EmptyShell);
    291 
    292   unsigned getCollapsedNumber() const { return CollapsedNum; }
    293 
    294   static bool classof(const Stmt *T) {
    295     return T->getStmtClass() == OMPSimdDirectiveClass;
    296   }
    297 };
    298 
    299 /// \brief This represents '#pragma omp for' directive.
    300 ///
    301 /// \code
    302 /// #pragma omp for private(a,b) reduction(+:c,d)
    303 /// \endcode
    304 /// In this example directive '#pragma omp for' has clauses 'private' with the
    305 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
    306 /// and 'd'.
    307 ///
    308 class OMPForDirective : public OMPExecutableDirective {
    309   friend class ASTStmtReader;
    310   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    311   unsigned CollapsedNum;
    312   /// \brief Build directive with the given start and end location.
    313   ///
    314   /// \param StartLoc Starting location of the directive kind.
    315   /// \param EndLoc Ending location of the directive.
    316   /// \param CollapsedNum Number of collapsed nested loops.
    317   /// \param NumClauses Number of clauses.
    318   ///
    319   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    320                   unsigned CollapsedNum, unsigned NumClauses)
    321       : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
    322                                EndLoc, NumClauses, 1),
    323         CollapsedNum(CollapsedNum) {}
    324 
    325   /// \brief Build an empty directive.
    326   ///
    327   /// \param CollapsedNum Number of collapsed nested loops.
    328   /// \param NumClauses Number of clauses.
    329   ///
    330   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
    331       : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
    332                                SourceLocation(), SourceLocation(), NumClauses,
    333                                1),
    334         CollapsedNum(CollapsedNum) {}
    335 
    336 public:
    337   /// \brief Creates directive with a list of \a Clauses.
    338   ///
    339   /// \param C AST context.
    340   /// \param StartLoc Starting location of the directive kind.
    341   /// \param EndLoc Ending Location of the directive.
    342   /// \param CollapsedNum Number of collapsed loops.
    343   /// \param Clauses List of clauses.
    344   /// \param AssociatedStmt Statement, associated with the directive.
    345   ///
    346   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    347                                  SourceLocation EndLoc, unsigned CollapsedNum,
    348                                  ArrayRef<OMPClause *> Clauses,
    349                                  Stmt *AssociatedStmt);
    350 
    351   /// \brief Creates an empty directive with the place
    352   /// for \a NumClauses clauses.
    353   ///
    354   /// \param C AST context.
    355   /// \param CollapsedNum Number of collapsed nested loops.
    356   /// \param NumClauses Number of clauses.
    357   ///
    358   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    359                                       unsigned CollapsedNum, EmptyShell);
    360 
    361   unsigned getCollapsedNumber() const { return CollapsedNum; }
    362 
    363   static bool classof(const Stmt *T) {
    364     return T->getStmtClass() == OMPForDirectiveClass;
    365   }
    366 };
    367 
    368 /// \brief This represents '#pragma omp sections' directive.
    369 ///
    370 /// \code
    371 /// #pragma omp sections private(a,b) reduction(+:c,d)
    372 /// \endcode
    373 /// In this example directive '#pragma omp sections' has clauses 'private' with
    374 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
    375 /// 'c' and 'd'.
    376 ///
    377 class OMPSectionsDirective : public OMPExecutableDirective {
    378   friend class ASTStmtReader;
    379   /// \brief Build directive with the given start and end location.
    380   ///
    381   /// \param StartLoc Starting location of the directive kind.
    382   /// \param EndLoc Ending location of the directive.
    383   /// \param NumClauses Number of clauses.
    384   ///
    385   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    386                        unsigned NumClauses)
    387       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    388                                StartLoc, EndLoc, NumClauses, 1) {}
    389 
    390   /// \brief Build an empty directive.
    391   ///
    392   /// \param NumClauses Number of clauses.
    393   ///
    394   explicit OMPSectionsDirective(unsigned NumClauses)
    395       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    396                                SourceLocation(), SourceLocation(), NumClauses,
    397                                1) {}
    398 
    399 public:
    400   /// \brief Creates directive with a list of \a Clauses.
    401   ///
    402   /// \param C AST context.
    403   /// \param StartLoc Starting location of the directive kind.
    404   /// \param EndLoc Ending Location of the directive.
    405   /// \param Clauses List of clauses.
    406   /// \param AssociatedStmt Statement, associated with the directive.
    407   ///
    408   static OMPSectionsDirective *
    409   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    410          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    411 
    412   /// \brief Creates an empty directive with the place for \a NumClauses
    413   /// clauses.
    414   ///
    415   /// \param C AST context.
    416   /// \param NumClauses Number of clauses.
    417   ///
    418   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
    419                                            unsigned NumClauses, EmptyShell);
    420 
    421   static bool classof(const Stmt *T) {
    422     return T->getStmtClass() == OMPSectionsDirectiveClass;
    423   }
    424 };
    425 
    426 /// \brief This represents '#pragma omp section' directive.
    427 ///
    428 /// \code
    429 /// #pragma omp section
    430 /// \endcode
    431 ///
    432 class OMPSectionDirective : public OMPExecutableDirective {
    433   friend class ASTStmtReader;
    434   /// \brief Build directive with the given start and end location.
    435   ///
    436   /// \param StartLoc Starting location of the directive kind.
    437   /// \param EndLoc Ending location of the directive.
    438   ///
    439   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
    440       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
    441                                StartLoc, EndLoc, 0, 1) {}
    442 
    443   /// \brief Build an empty directive.
    444   ///
    445   explicit OMPSectionDirective()
    446       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
    447                                SourceLocation(), SourceLocation(), 0, 1) {}
    448 
    449 public:
    450   /// \brief Creates directive.
    451   ///
    452   /// \param C AST context.
    453   /// \param StartLoc Starting location of the directive kind.
    454   /// \param EndLoc Ending Location of the directive.
    455   /// \param AssociatedStmt Statement, associated with the directive.
    456   ///
    457   static OMPSectionDirective *Create(const ASTContext &C,
    458                                      SourceLocation StartLoc,
    459                                      SourceLocation EndLoc,
    460                                      Stmt *AssociatedStmt);
    461 
    462   /// \brief Creates an empty directive.
    463   ///
    464   /// \param C AST context.
    465   ///
    466   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
    467 
    468   static bool classof(const Stmt *T) {
    469     return T->getStmtClass() == OMPSectionDirectiveClass;
    470   }
    471 };
    472 
    473 /// \brief This represents '#pragma omp single' directive.
    474 ///
    475 /// \code
    476 /// #pragma omp single private(a,b) copyprivate(c,d)
    477 /// \endcode
    478 /// In this example directive '#pragma omp single' has clauses 'private' with
    479 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
    480 ///
    481 class OMPSingleDirective : public OMPExecutableDirective {
    482   friend class ASTStmtReader;
    483   /// \brief Build directive with the given start and end location.
    484   ///
    485   /// \param StartLoc Starting location of the directive kind.
    486   /// \param EndLoc Ending location of the directive.
    487   /// \param NumClauses Number of clauses.
    488   ///
    489   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    490                      unsigned NumClauses)
    491       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
    492                                StartLoc, EndLoc, NumClauses, 1) {}
    493 
    494   /// \brief Build an empty directive.
    495   ///
    496   /// \param NumClauses Number of clauses.
    497   ///
    498   explicit OMPSingleDirective(unsigned NumClauses)
    499       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
    500                                SourceLocation(), SourceLocation(), NumClauses,
    501                                1) {}
    502 
    503 public:
    504   /// \brief Creates directive with a list of \a Clauses.
    505   ///
    506   /// \param C AST context.
    507   /// \param StartLoc Starting location of the directive kind.
    508   /// \param EndLoc Ending Location of the directive.
    509   /// \param Clauses List of clauses.
    510   /// \param AssociatedStmt Statement, associated with the directive.
    511   ///
    512   static OMPSingleDirective *
    513   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    514          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    515 
    516   /// \brief Creates an empty directive with the place for \a NumClauses
    517   /// clauses.
    518   ///
    519   /// \param C AST context.
    520   /// \param NumClauses Number of clauses.
    521   ///
    522   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
    523                                          unsigned NumClauses, EmptyShell);
    524 
    525   static bool classof(const Stmt *T) {
    526     return T->getStmtClass() == OMPSingleDirectiveClass;
    527   }
    528 };
    529 
    530 /// \brief This represents '#pragma omp parallel for' directive.
    531 ///
    532 /// \code
    533 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
    534 /// \endcode
    535 /// In this example directive '#pragma omp parallel for' has clauses 'private'
    536 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    537 /// variables 'c' and 'd'.
    538 ///
    539 class OMPParallelForDirective : public OMPExecutableDirective {
    540   friend class ASTStmtReader;
    541   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    542   unsigned CollapsedNum;
    543   /// \brief Build directive with the given start and end location.
    544   ///
    545   /// \param StartLoc Starting location of the directive kind.
    546   /// \param EndLoc Ending location of the directive.
    547   /// \param CollapsedNum Number of collapsed nested loops.
    548   /// \param NumClauses Number of clauses.
    549   ///
    550   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    551                           unsigned CollapsedNum, unsigned NumClauses)
    552       : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
    553                                OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
    554                                1),
    555         CollapsedNum(CollapsedNum) {}
    556 
    557   /// \brief Build an empty directive.
    558   ///
    559   /// \param CollapsedNum Number of collapsed nested loops.
    560   /// \param NumClauses Number of clauses.
    561   ///
    562   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
    563       : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
    564                                OMPD_parallel_for, SourceLocation(),
    565                                SourceLocation(), NumClauses, 1),
    566         CollapsedNum(CollapsedNum) {}
    567 
    568 public:
    569   /// \brief Creates directive with a list of \a Clauses.
    570   ///
    571   /// \param C AST context.
    572   /// \param StartLoc Starting location of the directive kind.
    573   /// \param EndLoc Ending Location of the directive.
    574   /// \param CollapsedNum Number of collapsed loops.
    575   /// \param Clauses List of clauses.
    576   /// \param AssociatedStmt Statement, associated with the directive.
    577   ///
    578   static OMPParallelForDirective *
    579   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    580          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
    581          Stmt *AssociatedStmt);
    582 
    583   /// \brief Creates an empty directive with the place
    584   /// for \a NumClauses clauses.
    585   ///
    586   /// \param C AST context.
    587   /// \param CollapsedNum Number of collapsed nested loops.
    588   /// \param NumClauses Number of clauses.
    589   ///
    590   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
    591                                               unsigned NumClauses,
    592                                               unsigned CollapsedNum,
    593                                               EmptyShell);
    594 
    595   unsigned getCollapsedNumber() const { return CollapsedNum; }
    596 
    597   static bool classof(const Stmt *T) {
    598     return T->getStmtClass() == OMPParallelForDirectiveClass;
    599   }
    600 };
    601 
    602 /// \brief This represents '#pragma omp parallel sections' directive.
    603 ///
    604 /// \code
    605 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
    606 /// \endcode
    607 /// In this example directive '#pragma omp parallel sections' has clauses
    608 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
    609 /// and variables 'c' and 'd'.
    610 ///
    611 class OMPParallelSectionsDirective : public OMPExecutableDirective {
    612   friend class ASTStmtReader;
    613   /// \brief Build directive with the given start and end location.
    614   ///
    615   /// \param StartLoc Starting location of the directive kind.
    616   /// \param EndLoc Ending location of the directive.
    617   /// \param NumClauses Number of clauses.
    618   ///
    619   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    620                                unsigned NumClauses)
    621       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
    622                                OMPD_parallel_sections, StartLoc, EndLoc,
    623                                NumClauses, 1) {}
    624 
    625   /// \brief Build an empty directive.
    626   ///
    627   /// \param NumClauses Number of clauses.
    628   ///
    629   explicit OMPParallelSectionsDirective(unsigned NumClauses)
    630       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
    631                                OMPD_parallel_sections, SourceLocation(),
    632                                SourceLocation(), NumClauses, 1) {}
    633 
    634 public:
    635   /// \brief Creates directive with a list of \a Clauses.
    636   ///
    637   /// \param C AST context.
    638   /// \param StartLoc Starting location of the directive kind.
    639   /// \param EndLoc Ending Location of the directive.
    640   /// \param Clauses List of clauses.
    641   /// \param AssociatedStmt Statement, associated with the directive.
    642   ///
    643   static OMPParallelSectionsDirective *
    644   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    645          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    646 
    647   /// \brief Creates an empty directive with the place for \a NumClauses
    648   /// clauses.
    649   ///
    650   /// \param C AST context.
    651   /// \param NumClauses Number of clauses.
    652   ///
    653   static OMPParallelSectionsDirective *
    654   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
    655 
    656   static bool classof(const Stmt *T) {
    657     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
    658   }
    659 };
    660 
    661 } // end namespace clang
    662 
    663 #endif
    664