Home | History | Annotate | Download | only in AST
      1 //===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- 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/Basic/OpenMPKinds.h"
     19 #include "clang/Basic/SourceLocation.h"
     20 #include "clang/AST/Expr.h"
     21 #include "clang/AST/Stmt.h"
     22 
     23 namespace clang {
     24 
     25 //===----------------------------------------------------------------------===//
     26 // AST classes for clauses.
     27 //===----------------------------------------------------------------------===//
     28 
     29 /// \brief This is a basic class for representing single OpenMP clause.
     30 ///
     31 class OMPClause {
     32   /// \brief Starting location of the clause (the clause keyword).
     33   SourceLocation StartLoc;
     34   /// \brief Ending location of the clause.
     35   SourceLocation EndLoc;
     36   /// \brief Kind of the clause.
     37   OpenMPClauseKind Kind;
     38 protected:
     39   OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
     40     : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
     41 
     42 public:
     43 
     44   /// \brief Returns the starting location of the clause.
     45   SourceLocation getLocStart() const { return StartLoc; }
     46   /// \brief Returns the ending location of the clause.
     47   SourceLocation getLocEnd() const { return EndLoc; }
     48 
     49   /// \brief Sets the starting location of the clause.
     50   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
     51   /// \brief Sets the ending location of the clause.
     52   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
     53 
     54   /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
     55   OpenMPClauseKind getClauseKind() const { return Kind; }
     56 
     57   bool isImplicit() const { return StartLoc.isInvalid();}
     58 
     59   StmtRange children();
     60   ConstStmtRange children() const {
     61     return const_cast<OMPClause *>(this)->children();
     62   }
     63   static bool classof(const OMPClause *T) {
     64     return true;
     65   }
     66 };
     67 
     68 /// \brief This represents clauses with the list of variables like 'private',
     69 /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
     70 /// '#pragma omp ...' directives.
     71 template <class T>
     72 class OMPVarList {
     73   friend class OMPClauseReader;
     74   /// \brief Location of '('.
     75   SourceLocation LParenLoc;
     76   /// \brief Number of variables in the list.
     77   unsigned NumVars;
     78 protected:
     79   /// \brief Fetches list of variables associated with this clause.
     80   llvm::MutableArrayRef<Expr *> getVarRefs() {
     81     return llvm::MutableArrayRef<Expr *>(
     82                          reinterpret_cast<Expr **>(static_cast<T *>(this) + 1),
     83                          NumVars);
     84   }
     85 
     86   /// \brief Sets the list of variables for this clause.
     87   void setVarRefs(ArrayRef<Expr *> VL) {
     88     assert(VL.size() == NumVars &&
     89            "Number of variables is not the same as the preallocated buffer");
     90     std::copy(VL.begin(), VL.end(),
     91               reinterpret_cast<Expr **>(static_cast<T *>(this) + 1));
     92   }
     93 
     94   /// \brief Build clause with number of variables \a N.
     95   ///
     96   /// \param N Number of the variables in the clause.
     97   ///
     98   OMPVarList(SourceLocation LParenLoc, unsigned N)
     99     : LParenLoc(LParenLoc), NumVars(N) { }
    100 public:
    101   typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
    102   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
    103 
    104   unsigned varlist_size() const { return NumVars; }
    105   bool varlist_empty() const { return NumVars == 0; }
    106   varlist_iterator varlist_begin() { return getVarRefs().begin(); }
    107   varlist_iterator varlist_end() { return getVarRefs().end(); }
    108   varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
    109   varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
    110 
    111   /// \brief Sets the location of '('.
    112   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
    113   /// \brief Returns the location of '('.
    114   SourceLocation getLParenLoc() const { return LParenLoc; }
    115 
    116   /// \brief Fetches list of all variables in the clause.
    117   ArrayRef<const Expr *> getVarRefs() const {
    118     return ArrayRef<const Expr *>(
    119        reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1),
    120        NumVars);
    121   }
    122 };
    123 
    124 /// \brief This represents 'default' clause in the '#pragma omp ...' directive.
    125 ///
    126 /// \code
    127 /// #pragma omp parallel default(shared)
    128 /// \endcode
    129 /// In this example directive '#pragma omp parallel' has simple 'default'
    130 /// clause with kind 'shared'.
    131 ///
    132 class OMPDefaultClause : public OMPClause {
    133   friend class OMPClauseReader;
    134   /// \brief Location of '('.
    135   SourceLocation LParenLoc;
    136   /// \brief A kind of the 'default' clause.
    137   OpenMPDefaultClauseKind Kind;
    138   /// \brief Start location of the kind in source code.
    139   SourceLocation KindKwLoc;
    140 
    141   /// \brief Set kind of the clauses.
    142   ///
    143   /// \param K Argument of clause.
    144   ///
    145   void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
    146 
    147   /// \brief Set argument location.
    148   ///
    149   /// \param KLoc Argument location.
    150   ///
    151   void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
    152 public:
    153   /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
    154   ///
    155   /// \param A Argument of the clause ('none' or 'shared').
    156   /// \param ALoc Starting location of the argument.
    157   /// \param StartLoc Starting location of the clause.
    158   /// \param LParenLoc Location of '('.
    159   /// \param EndLoc Ending location of the clause.
    160   ///
    161   OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
    162                    SourceLocation StartLoc, SourceLocation LParenLoc,
    163                    SourceLocation EndLoc)
    164     : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
    165       Kind(A), KindKwLoc(ALoc) { }
    166 
    167   /// \brief Build an empty clause.
    168   ///
    169   OMPDefaultClause()
    170     : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
    171       LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
    172       KindKwLoc(SourceLocation()) { }
    173 
    174   /// \brief Sets the location of '('.
    175   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
    176   /// \brief Returns the location of '('.
    177   SourceLocation getLParenLoc() const { return LParenLoc; }
    178 
    179   /// \brief Returns kind of the clause.
    180   OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
    181 
    182   /// \brief Returns location of clause kind.
    183   SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
    184 
    185   static bool classof(const OMPClause *T) {
    186     return T->getClauseKind() == OMPC_default;
    187   }
    188 
    189   StmtRange children() {
    190     return StmtRange();
    191   }
    192 };
    193 
    194 /// \brief This represents clause 'private' in the '#pragma omp ...' directives.
    195 ///
    196 /// \code
    197 /// #pragma omp parallel private(a,b)
    198 /// \endcode
    199 /// In this example directive '#pragma omp parallel' has clause 'private'
    200 /// with the variables 'a' and 'b'.
    201 ///
    202 class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> {
    203   /// \brief Build clause with number of variables \a N.
    204   ///
    205   /// \param StartLoc Starting location of the clause.
    206   /// \param LParenLoc Location of '('.
    207   /// \param EndLoc Ending location of the clause.
    208   /// \param N Number of the variables in the clause.
    209   ///
    210   OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
    211                    SourceLocation EndLoc, unsigned N)
    212     : OMPClause(OMPC_private, StartLoc, EndLoc),
    213       OMPVarList<OMPPrivateClause>(LParenLoc, N) { }
    214 
    215   /// \brief Build an empty clause.
    216   ///
    217   /// \param N Number of variables.
    218   ///
    219   explicit OMPPrivateClause(unsigned N)
    220     : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
    221       OMPVarList<OMPPrivateClause>(SourceLocation(), N) { }
    222 public:
    223   /// \brief Creates clause with a list of variables \a VL.
    224   ///
    225   /// \param C AST context.
    226   /// \param StartLoc Starting location of the clause.
    227   /// \param LParenLoc Location of '('.
    228   /// \param EndLoc Ending location of the clause.
    229   /// \param VL List of references to the variables.
    230   ///
    231   static OMPPrivateClause *Create(ASTContext &C, SourceLocation StartLoc,
    232                                   SourceLocation LParenLoc,
    233                                   SourceLocation EndLoc,
    234                                   ArrayRef<Expr *> VL);
    235   /// \brief Creates an empty clause with the place for \a N variables.
    236   ///
    237   /// \param C AST context.
    238   /// \param N The number of variables.
    239   ///
    240   static OMPPrivateClause *CreateEmpty(ASTContext &C, unsigned N);
    241 
    242   StmtRange children() {
    243     return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
    244                      reinterpret_cast<Stmt **>(varlist_end()));
    245   }
    246 
    247   static bool classof(const OMPClause *T) {
    248     return T->getClauseKind() == OMPC_private;
    249   }
    250 };
    251 
    252 //===----------------------------------------------------------------------===//
    253 // AST classes for directives.
    254 //===----------------------------------------------------------------------===//
    255 
    256 /// \brief This is a basic class for representing single OpenMP executable
    257 /// directive.
    258 ///
    259 class OMPExecutableDirective : public Stmt {
    260   friend class ASTStmtReader;
    261   /// \brief Kind of the directive.
    262   OpenMPDirectiveKind Kind;
    263   /// \brief Starting location of the directive (directive keyword).
    264   SourceLocation StartLoc;
    265   /// \brief Ending location of the directive.
    266   SourceLocation EndLoc;
    267   /// \brief Pointer to the list of clauses.
    268   llvm::MutableArrayRef<OMPClause *> Clauses;
    269   /// \brief Associated statement (if any) and expressions.
    270   llvm::MutableArrayRef<Stmt *> StmtAndExpressions;
    271 protected:
    272   /// \brief Build instance of directive of class \a K.
    273   ///
    274   /// \param SC Statement class.
    275   /// \param K Kind of OpenMP directive.
    276   /// \param StartLoc Starting location of the directive (directive keyword).
    277   /// \param EndLoc Ending location of the directive.
    278   ///
    279   template <typename T>
    280   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
    281                          SourceLocation StartLoc, SourceLocation EndLoc,
    282                          unsigned NumClauses, unsigned NumberOfExpressions)
    283     : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
    284       Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1),
    285               NumClauses),
    286       StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()),
    287                          NumberOfExpressions) { }
    288 
    289   /// \brief Sets the list of variables for this clause.
    290   ///
    291   /// \param Clauses The list of clauses for the directive.
    292   ///
    293   void setClauses(ArrayRef<OMPClause *> Clauses);
    294 
    295   /// \brief Set the associated statement for the directive.
    296   ///
    297   /// /param S Associated statement.
    298   ///
    299   void setAssociatedStmt(Stmt *S) {
    300     StmtAndExpressions[0] = S;
    301   }
    302 
    303 public:
    304   /// \brief Returns starting location of directive kind.
    305   SourceLocation getLocStart() const { return StartLoc; }
    306   /// \brief Returns ending location of directive.
    307   SourceLocation getLocEnd() const { return EndLoc; }
    308 
    309   /// \brief Set starting location of directive kind.
    310   ///
    311   /// \param Loc New starting location of directive.
    312   ///
    313   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    314   /// \brief Set ending location of directive.
    315   ///
    316   /// \param Loc New ending location of directive.
    317   ///
    318   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    319 
    320   /// \brief Get number of clauses.
    321   unsigned getNumClauses() const { return Clauses.size(); }
    322 
    323   /// \brief Returns specified clause.
    324   ///
    325   /// \param i Number of clause.
    326   ///
    327   OMPClause *getClause(unsigned i) const {
    328     assert(i < Clauses.size() && "index out of bound!");
    329     return Clauses[i];
    330   }
    331 
    332   /// \brief Returns statement associated with the directive.
    333   Stmt *getAssociatedStmt() const {
    334     return StmtAndExpressions[0];
    335   }
    336 
    337   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    338 
    339   static bool classof(const Stmt *S) {
    340     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    341            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    342   }
    343 
    344   child_range children() {
    345     return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end());
    346   }
    347 
    348   ArrayRef<OMPClause *> clauses() { return Clauses; }
    349 
    350   ArrayRef<OMPClause *> clauses() const { return Clauses; }
    351 };
    352 
    353 /// \brief This represents '#pragma omp parallel' directive.
    354 ///
    355 /// \code
    356 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    357 /// \endcode
    358 /// In this example directive '#pragma omp parallel' has clauses 'private'
    359 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    360 /// variables 'c' and 'd'.
    361 ///
    362 class OMPParallelDirective : public OMPExecutableDirective {
    363   /// \brief Build directive with the given start and end location.
    364   ///
    365   /// \param StartLoc Starting location of the directive (directive keyword).
    366   /// \param EndLoc Ending Location of the directive.
    367   ///
    368   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    369                        unsigned N)
    370     : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    371                              StartLoc, EndLoc, N, 1) { }
    372 
    373   /// \brief Build an empty directive.
    374   ///
    375   /// \param N Number of clauses.
    376   ///
    377   explicit OMPParallelDirective(unsigned N)
    378     : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    379                              SourceLocation(), SourceLocation(), N, 1) { }
    380 public:
    381   /// \brief Creates directive with a list of \a Clauses.
    382   ///
    383   /// \param C AST context.
    384   /// \param StartLoc Starting location of the directive kind.
    385   /// \param EndLoc Ending Location of the directive.
    386   /// \param Clauses List of clauses.
    387   /// \param AssociatedStmt Statement associated with the directive.
    388   ///
    389   static OMPParallelDirective *Create(ASTContext &C, SourceLocation StartLoc,
    390                                       SourceLocation EndLoc,
    391                                       ArrayRef<OMPClause *> Clauses,
    392                                       Stmt *AssociatedStmt);
    393 
    394   /// \brief Creates an empty directive with the place for \a N clauses.
    395   ///
    396   /// \param C AST context.
    397   /// \param N The number of clauses.
    398   ///
    399   static OMPParallelDirective *CreateEmpty(ASTContext &C, unsigned N,
    400                                            EmptyShell);
    401 
    402   static bool classof(const Stmt *T) {
    403     return T->getStmtClass() == OMPParallelDirectiveClass;
    404   }
    405 };
    406 
    407 }  // end namespace clang
    408 
    409 #endif
    410