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 OMPThreadPrivateDecl(Kind DK,DeclContext * DC,SourceLocation L)49 OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) : 50 Decl(DK, DC, L), NumVars(0) { } 51 getVars()52 ArrayRef<const Expr *> getVars() const { 53 return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars); 54 } 55 getVars()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 varlist_size()74 unsigned varlist_size() const { return NumVars; } varlist_empty()75 bool varlist_empty() const { return NumVars == 0; } 76 varlists()77 varlist_range varlists() { 78 return varlist_range(varlist_begin(), varlist_end()); 79 } varlists()80 varlist_const_range varlists() const { 81 return varlist_const_range(varlist_begin(), varlist_end()); 82 } varlist_begin()83 varlist_iterator varlist_begin() { return getVars().begin(); } varlist_end()84 varlist_iterator varlist_end() { return getVars().end(); } varlist_begin()85 varlist_const_iterator varlist_begin() const { return getVars().begin(); } varlist_end()86 varlist_const_iterator varlist_end() const { return getVars().end(); } 87 classof(const Decl * D)88 static bool classof(const Decl *D) { return classofKind(D->getKind()); } classofKind(Kind K)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 private: 104 friend class ASTDeclReader; 105 /// \brief Combiner for declare reduction construct. 106 Expr *Combiner; 107 /// \brief Initializer for declare reduction construct. 108 Expr *Initializer; 109 /// \brief Reference to the previous declare reduction construct in the same 110 /// scope with the same name. Required for proper templates instantiation if 111 /// the declare reduction construct is declared inside compound statement. 112 LazyDeclPtr PrevDeclInScope; 113 114 virtual void anchor(); 115 OMPDeclareReductionDecl(Kind DK,DeclContext * DC,SourceLocation L,DeclarationName Name,QualType Ty,OMPDeclareReductionDecl * PrevDeclInScope)116 OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, 117 DeclarationName Name, QualType Ty, 118 OMPDeclareReductionDecl *PrevDeclInScope) 119 : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), 120 Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {} 121 setPrevDeclInScope(OMPDeclareReductionDecl * Prev)122 void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { 123 PrevDeclInScope = Prev; 124 } 125 126 public: 127 /// \brief Create declare reduction node. 128 static OMPDeclareReductionDecl * 129 Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, 130 QualType T, OMPDeclareReductionDecl *PrevDeclInScope); 131 /// \brief Create deserialized declare reduction node. 132 static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, 133 unsigned ID); 134 135 /// \brief Get combiner expression of the declare reduction construct. getCombiner()136 Expr *getCombiner() { return Combiner; } getCombiner()137 const Expr *getCombiner() const { return Combiner; } 138 /// \brief Set combiner expression for the declare reduction construct. setCombiner(Expr * E)139 void setCombiner(Expr *E) { Combiner = E; } 140 141 /// \brief Get initializer expression (if specified) of the declare reduction 142 /// construct. getInitializer()143 Expr *getInitializer() { return Initializer; } getInitializer()144 const Expr *getInitializer() const { return Initializer; } 145 /// \brief Set initializer expression for the declare reduction construct. setInitializer(Expr * E)146 void setInitializer(Expr *E) { Initializer = E; } 147 148 /// \brief Get reference to previous declare reduction construct in the same 149 /// scope with the same name. 150 OMPDeclareReductionDecl *getPrevDeclInScope(); 151 const OMPDeclareReductionDecl *getPrevDeclInScope() const; 152 classof(const Decl * D)153 static bool classof(const Decl *D) { return classofKind(D->getKind()); } classofKind(Kind K)154 static bool classofKind(Kind K) { return K == OMPDeclareReduction; } castToDeclContext(const OMPDeclareReductionDecl * D)155 static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) { 156 return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D)); 157 } castFromDeclContext(const DeclContext * DC)158 static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) { 159 return static_cast<OMPDeclareReductionDecl *>( 160 const_cast<DeclContext *>(DC)); 161 } 162 }; 163 164 /// Pseudo declaration for capturing expressions. Also is used for capturing of 165 /// non-static data members in non-static member functions. 166 /// 167 /// Clang supports capturing of variables only, but OpenMP 4.5 allows to 168 /// privatize non-static members of current class in non-static member 169 /// functions. This pseudo-declaration allows properly handle this kind of 170 /// capture by wrapping captured expression into a variable-like declaration. 171 class OMPCapturedExprDecl final : public VarDecl { 172 friend class ASTDeclReader; 173 void anchor() override; 174 OMPCapturedExprDecl(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,QualType Type)175 OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, 176 QualType Type) 177 : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id, 178 Type, nullptr, SC_None) { 179 setImplicit(); 180 } 181 182 public: 183 static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC, 184 IdentifierInfo *Id, QualType T); 185 186 static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID); 187 188 // Implement isa/cast/dyncast/etc. classof(const Decl * D)189 static bool classof(const Decl *D) { return classofKind(D->getKind()); } classofKind(Kind K)190 static bool classofKind(Kind K) { return K == OMPCapturedExpr; } 191 }; 192 193 } // end namespace clang 194 195 #endif 196