1 //===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file defines OpenMP nodes for declarative directives.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_DECLOPENMP_H
16 #define LLVM_CLANG_AST_DECLOPENMP_H
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"
27 /// This represents '#pragma omp threadprivate ...' directive.
28 /// For example, in the following, both 'a' and 'A::b' are threadprivate:
32 /// #pragma omp threadprivate(a)
35 /// #pragma omp threadprivate(b)
39 class OMPThreadPrivateDecl final
41 private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
42 friend class ASTDeclReader;
43 friend TrailingObjects;
47 virtual void anchor();
49 OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
50 Decl(DK, DC, L), NumVars(0) { }
52 ArrayRef<const Expr *> getVars() const {
53 return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
56 MutableArrayRef<Expr *> getVars() {
57 return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
60 void setVars(ArrayRef<Expr *> VL);
63 static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
66 static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
67 unsigned ID, unsigned N);
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;
74 unsigned varlist_size() const { return NumVars; }
75 bool varlist_empty() const { return NumVars == 0; }
77 varlist_range varlists() {
78 return varlist_range(varlist_begin(), varlist_end());
80 varlist_const_range varlists() const {
81 return varlist_const_range(varlist_begin(), varlist_end());
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(); }
88 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
89 static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
92 /// This represents '#pragma omp declare reduction ...' directive.
93 /// For example, in the following, declared reduction 'foo' for types 'int' and
97 /// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
98 /// initializer (omp_priv = 0)
101 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
102 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
105 CallInit, // Initialized by function call.
106 DirectInit, // omp_priv(<expr>)
107 CopyInit // omp_priv = <expr>
111 friend class ASTDeclReader;
112 /// Combiner for declare reduction construct.
114 /// Initializer for declare reduction construct.
116 /// Kind of initializer - function call or omp_priv<init_expr> initializtion.
117 InitKind InitializerKind = CallInit;
119 /// 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;
124 virtual void anchor();
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) {}
133 void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
134 PrevDeclInScope = Prev;
138 /// Create declare reduction node.
139 static OMPDeclareReductionDecl *
140 Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
141 QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
142 /// Create deserialized declare reduction node.
143 static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
146 /// Get combiner expression of the declare reduction construct.
147 Expr *getCombiner() { return Combiner; }
148 const Expr *getCombiner() const { return Combiner; }
149 /// Set combiner expression for the declare reduction construct.
150 void setCombiner(Expr *E) { Combiner = E; }
152 /// Get initializer expression (if specified) of the declare reduction
154 Expr *getInitializer() { return Initializer; }
155 const Expr *getInitializer() const { return Initializer; }
156 /// Get initializer kind.
157 InitKind getInitializerKind() const { return InitializerKind; }
158 /// Set initializer expression for the declare reduction construct.
159 void setInitializer(Expr *E, InitKind IK) {
161 InitializerKind = IK;
164 /// Get reference to previous declare reduction construct in the same
165 /// scope with the same name.
166 OMPDeclareReductionDecl *getPrevDeclInScope();
167 const OMPDeclareReductionDecl *getPrevDeclInScope() const;
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));
174 static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
175 return static_cast<OMPDeclareReductionDecl *>(
176 const_cast<DeclContext *>(DC));
180 /// Pseudo declaration for capturing expressions. Also is used for capturing of
181 /// non-static data members in non-static member functions.
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;
191 OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
192 QualType Type, TypeSourceInfo *TInfo,
193 SourceLocation StartLoc)
194 : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
200 static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
201 IdentifierInfo *Id, QualType T,
202 SourceLocation StartLoc);
204 static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
206 SourceRange getSourceRange() const override LLVM_READONLY;
208 // Implement isa/cast/dyncast/etc.
209 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
210 static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
213 } // end namespace clang