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