Home | History | Annotate | Download | only in AST
      1 //===- DeclOpenMP.h - Classes for representing 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 ///
     10 /// \file
     11 /// \brief This file defines OpenMP nodes for declarative directives.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_DECLOPENMP_H
     16 #define LLVM_CLANG_AST_DECLOPENMP_H
     17 
     18 #include "clang/AST/Decl.h"
     19 #include "clang/AST/Expr.h"
     20 #include "clang/AST/ExternalASTSource.h"
     21 #include "clang/AST/Type.h"
     22 #include "llvm/ADT/ArrayRef.h"
     23 #include "llvm/Support/TrailingObjects.h"
     24 
     25 namespace clang {
     26 
     27 /// \brief This represents '#pragma omp threadprivate ...' directive.
     28 /// For example, in the following, both 'a' and 'A::b' are threadprivate:
     29 ///
     30 /// \code
     31 /// int a;
     32 /// #pragma omp threadprivate(a)
     33 /// struct A {
     34 ///   static int b;
     35 /// #pragma omp threadprivate(b)
     36 /// };
     37 /// \endcode
     38 ///
     39 class OMPThreadPrivateDecl final
     40     : public Decl,
     41       private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
     42   friend class ASTDeclReader;
     43   friend TrailingObjects;
     44 
     45   unsigned NumVars;
     46 
     47   virtual void anchor();
     48 
     49   OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
     50     Decl(DK, DC, L), NumVars(0) { }
     51 
     52   ArrayRef<const Expr *> getVars() const {
     53     return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
     54   }
     55 
     56   MutableArrayRef<Expr *> getVars() {
     57     return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
     58   }
     59 
     60   void setVars(ArrayRef<Expr *> VL);
     61 
     62 public:
     63   static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
     64                                       SourceLocation L,
     65                                       ArrayRef<Expr *> VL);
     66   static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
     67                                                   unsigned ID, unsigned N);
     68 
     69   typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
     70   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
     71   typedef llvm::iterator_range<varlist_iterator> varlist_range;
     72   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
     73 
     74   unsigned varlist_size() const { return NumVars; }
     75   bool varlist_empty() const { return NumVars == 0; }
     76 
     77   varlist_range varlists() {
     78     return varlist_range(varlist_begin(), varlist_end());
     79   }
     80   varlist_const_range varlists() const {
     81     return varlist_const_range(varlist_begin(), varlist_end());
     82   }
     83   varlist_iterator varlist_begin() { return getVars().begin(); }
     84   varlist_iterator varlist_end() { return getVars().end(); }
     85   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
     86   varlist_const_iterator varlist_end() const { return getVars().end(); }
     87 
     88   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
     89   static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
     90 };
     91 
     92 /// \brief This represents '#pragma omp declare reduction ...' directive.
     93 /// For example, in the following, declared reduction 'foo' for types 'int' and
     94 /// 'float':
     95 ///
     96 /// \code
     97 /// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
     98 ///                     initializer (omp_priv = 0)
     99 /// \endcode
    100 ///
    101 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
    102 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
    103 public:
    104   enum InitKind {
    105     CallInit,   // Initialized by function call.
    106     DirectInit, // omp_priv(<expr>)
    107     CopyInit    // omp_priv = <expr>
    108   };
    109 
    110 private:
    111   friend class ASTDeclReader;
    112   /// \brief Combiner for declare reduction construct.
    113   Expr *Combiner;
    114   /// \brief Initializer for declare reduction construct.
    115   Expr *Initializer;
    116   /// Kind of initializer - function call or omp_priv<init_expr> initializtion.
    117   InitKind InitializerKind = CallInit;
    118 
    119   /// \brief Reference to the previous declare reduction construct in the same
    120   /// scope with the same name. Required for proper templates instantiation if
    121   /// the declare reduction construct is declared inside compound statement.
    122   LazyDeclPtr PrevDeclInScope;
    123 
    124   virtual void anchor();
    125 
    126   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
    127                           DeclarationName Name, QualType Ty,
    128                           OMPDeclareReductionDecl *PrevDeclInScope)
    129       : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
    130         Initializer(nullptr), InitializerKind(CallInit),
    131         PrevDeclInScope(PrevDeclInScope) {}
    132 
    133   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
    134     PrevDeclInScope = Prev;
    135   }
    136 
    137 public:
    138   /// \brief Create declare reduction node.
    139   static OMPDeclareReductionDecl *
    140   Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
    141          QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
    142   /// \brief Create deserialized declare reduction node.
    143   static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
    144                                                      unsigned ID);
    145 
    146   /// \brief Get combiner expression of the declare reduction construct.
    147   Expr *getCombiner() { return Combiner; }
    148   const Expr *getCombiner() const { return Combiner; }
    149   /// \brief Set combiner expression for the declare reduction construct.
    150   void setCombiner(Expr *E) { Combiner = E; }
    151 
    152   /// \brief Get initializer expression (if specified) of the declare reduction
    153   /// construct.
    154   Expr *getInitializer() { return Initializer; }
    155   const Expr *getInitializer() const { return Initializer; }
    156   /// Get initializer kind.
    157   InitKind getInitializerKind() const { return InitializerKind; }
    158   /// \brief Set initializer expression for the declare reduction construct.
    159   void setInitializer(Expr *E, InitKind IK) {
    160     Initializer = E;
    161     InitializerKind = IK;
    162   }
    163 
    164   /// \brief Get reference to previous declare reduction construct in the same
    165   /// scope with the same name.
    166   OMPDeclareReductionDecl *getPrevDeclInScope();
    167   const OMPDeclareReductionDecl *getPrevDeclInScope() const;
    168 
    169   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
    170   static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
    171   static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
    172     return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
    173   }
    174   static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
    175     return static_cast<OMPDeclareReductionDecl *>(
    176         const_cast<DeclContext *>(DC));
    177   }
    178 };
    179 
    180 /// Pseudo declaration for capturing expressions. Also is used for capturing of
    181 /// non-static data members in non-static member functions.
    182 ///
    183 /// Clang supports capturing of variables only, but OpenMP 4.5 allows to
    184 /// privatize non-static members of current class in non-static member
    185 /// functions. This pseudo-declaration allows properly handle this kind of
    186 /// capture by wrapping captured expression into a variable-like declaration.
    187 class OMPCapturedExprDecl final : public VarDecl {
    188   friend class ASTDeclReader;
    189   void anchor() override;
    190 
    191   OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
    192                       QualType Type, SourceLocation StartLoc)
    193       : VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
    194                 nullptr, SC_None) {
    195     setImplicit();
    196   }
    197 
    198 public:
    199   static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
    200                                      IdentifierInfo *Id, QualType T,
    201                                      SourceLocation StartLoc);
    202 
    203   static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
    204 
    205   SourceRange getSourceRange() const override LLVM_READONLY;
    206 
    207   // Implement isa/cast/dyncast/etc.
    208   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
    209   static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
    210 };
    211 
    212 } // end namespace clang
    213 
    214 #endif
    215