• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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