xref: /aosp_15_r20/external/clang/include/clang/AST/DeclOpenMP.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
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