1 //===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file defines OpenMP nodes for declarative directives.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_DECLOPENMP_H
15 #define LLVM_CLANG_AST_DECLOPENMP_H
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/OpenMPClause.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 {
103 // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
104 // to save some space. Use the provided accessors to access it.
107 CallInit, // Initialized by function call.
108 DirectInit, // omp_priv(<expr>)
109 CopyInit // omp_priv = <expr>
113 friend class ASTDeclReader;
114 /// Combiner for declare reduction construct.
115 Expr *Combiner = nullptr;
116 /// Initializer for declare reduction construct.
117 Expr *Initializer = nullptr;
118 /// In parameter of the combiner.
120 /// Out parameter of the combiner.
122 /// Priv parameter of the initializer.
123 Expr *Priv = nullptr;
124 /// Orig parameter of the initializer.
125 Expr *Orig = nullptr;
127 /// Reference to the previous declare reduction construct in the same
128 /// scope with the same name. Required for proper templates instantiation if
129 /// the declare reduction construct is declared inside compound statement.
130 LazyDeclPtr PrevDeclInScope;
132 void anchor() override;
134 OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
135 DeclarationName Name, QualType Ty,
136 OMPDeclareReductionDecl *PrevDeclInScope);
138 void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
139 PrevDeclInScope = Prev;
143 /// Create declare reduction node.
144 static OMPDeclareReductionDecl *
145 Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
146 QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
147 /// Create deserialized declare reduction node.
148 static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
151 /// Get combiner expression of the declare reduction construct.
152 Expr *getCombiner() { return Combiner; }
153 const Expr *getCombiner() const { return Combiner; }
154 /// Get In variable of the combiner.
155 Expr *getCombinerIn() { return In; }
156 const Expr *getCombinerIn() const { return In; }
157 /// Get Out variable of the combiner.
158 Expr *getCombinerOut() { return Out; }
159 const Expr *getCombinerOut() const { return Out; }
160 /// Set combiner expression for the declare reduction construct.
161 void setCombiner(Expr *E) { Combiner = E; }
162 /// Set combiner In and Out vars.
163 void setCombinerData(Expr *InE, Expr *OutE) {
168 /// Get initializer expression (if specified) of the declare reduction
170 Expr *getInitializer() { return Initializer; }
171 const Expr *getInitializer() const { return Initializer; }
172 /// Get initializer kind.
173 InitKind getInitializerKind() const {
174 return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
176 /// Get Orig variable of the initializer.
177 Expr *getInitOrig() { return Orig; }
178 const Expr *getInitOrig() const { return Orig; }
179 /// Get Priv variable of the initializer.
180 Expr *getInitPriv() { return Priv; }
181 const Expr *getInitPriv() const { return Priv; }
182 /// Set initializer expression for the declare reduction construct.
183 void setInitializer(Expr *E, InitKind IK) {
185 OMPDeclareReductionDeclBits.InitializerKind = IK;
187 /// Set initializer Orig and Priv vars.
188 void setInitializerData(Expr *OrigE, Expr *PrivE) {
193 /// Get reference to previous declare reduction construct in the same
194 /// scope with the same name.
195 OMPDeclareReductionDecl *getPrevDeclInScope();
196 const OMPDeclareReductionDecl *getPrevDeclInScope() const;
198 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
199 static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
200 static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
201 return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
203 static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
204 return static_cast<OMPDeclareReductionDecl *>(
205 const_cast<DeclContext *>(DC));
209 /// This represents '#pragma omp declare mapper ...' directive. Map clauses are
210 /// allowed to use with this directive. The following example declares a user
211 /// defined mapper for the type 'struct vec'. This example instructs the fields
212 /// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.
215 /// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
217 class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
218 friend class ASTDeclReader;
220 /// Clauses associated with this mapper declaration
221 MutableArrayRef<OMPClause *> Clauses;
223 /// Mapper variable, which is 'v' in the example above
224 Expr *MapperVarRef = nullptr;
226 /// Name of the mapper variable
227 DeclarationName VarName;
229 LazyDeclPtr PrevDeclInScope;
231 void anchor() override;
233 OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L,
234 DeclarationName Name, QualType Ty,
235 DeclarationName VarName,
236 OMPDeclareMapperDecl *PrevDeclInScope)
237 : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName),
238 PrevDeclInScope(PrevDeclInScope) {}
240 void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
241 PrevDeclInScope = Prev;
244 /// Sets an array of clauses to this mapper declaration
245 void setClauses(ArrayRef<OMPClause *> CL);
248 /// Creates declare mapper node.
249 static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
250 SourceLocation L, DeclarationName Name,
251 QualType T, DeclarationName VarName,
252 OMPDeclareMapperDecl *PrevDeclInScope);
253 /// Creates deserialized declare mapper node.
254 static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,
257 /// Creates an array of clauses to this mapper declaration and intializes
259 void CreateClauses(ASTContext &C, ArrayRef<OMPClause *> CL);
261 using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
262 using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
263 using clauselist_range = llvm::iterator_range<clauselist_iterator>;
264 using clauselist_const_range =
265 llvm::iterator_range<clauselist_const_iterator>;
267 unsigned clauselist_size() const { return Clauses.size(); }
268 bool clauselist_empty() const { return Clauses.empty(); }
270 clauselist_range clauselists() {
271 return clauselist_range(clauselist_begin(), clauselist_end());
273 clauselist_const_range clauselists() const {
274 return clauselist_const_range(clauselist_begin(), clauselist_end());
276 clauselist_iterator clauselist_begin() { return Clauses.begin(); }
277 clauselist_iterator clauselist_end() { return Clauses.end(); }
278 clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); }
279 clauselist_const_iterator clauselist_end() const { return Clauses.end(); }
281 /// Get the variable declared in the mapper
282 Expr *getMapperVarRef() { return MapperVarRef; }
283 const Expr *getMapperVarRef() const { return MapperVarRef; }
284 /// Set the variable declared in the mapper
285 void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; }
287 /// Get the name of the variable declared in the mapper
288 DeclarationName getVarName() { return VarName; }
290 /// Get reference to previous declare mapper construct in the same
291 /// scope with the same name.
292 OMPDeclareMapperDecl *getPrevDeclInScope();
293 const OMPDeclareMapperDecl *getPrevDeclInScope() const;
295 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
296 static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
297 static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
298 return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
300 static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {
301 return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));
305 /// Pseudo declaration for capturing expressions. Also is used for capturing of
306 /// non-static data members in non-static member functions.
308 /// Clang supports capturing of variables only, but OpenMP 4.5 allows to
309 /// privatize non-static members of current class in non-static member
310 /// functions. This pseudo-declaration allows properly handle this kind of
311 /// capture by wrapping captured expression into a variable-like declaration.
312 class OMPCapturedExprDecl final : public VarDecl {
313 friend class ASTDeclReader;
314 void anchor() override;
316 OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
317 QualType Type, TypeSourceInfo *TInfo,
318 SourceLocation StartLoc)
319 : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
325 static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
326 IdentifierInfo *Id, QualType T,
327 SourceLocation StartLoc);
329 static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID);
331 SourceRange getSourceRange() const override LLVM_READONLY;
333 // Implement isa/cast/dyncast/etc.
334 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
335 static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
338 /// This represents '#pragma omp requires...' directive.
342 /// #pragma omp requires unified_address
345 class OMPRequiresDecl final
347 private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
348 friend class ASTDeclReader;
349 friend TrailingObjects;
351 // Number of clauses associated with this requires declaration
352 unsigned NumClauses = 0;
354 virtual void anchor();
356 OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
357 : Decl(DK, DC, L), NumClauses(0) {}
359 /// Returns an array of immutable clauses associated with this requires
361 ArrayRef<const OMPClause *> getClauses() const {
362 return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
365 /// Returns an array of clauses associated with this requires declaration
366 MutableArrayRef<OMPClause *> getClauses() {
367 return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
371 /// Sets an array of clauses to this requires declaration
372 void setClauses(ArrayRef<OMPClause *> CL);
375 /// Create requires node.
376 static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
377 SourceLocation L, ArrayRef<OMPClause *> CL);
378 /// Create deserialized requires node.
379 static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
382 using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
383 using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
384 using clauselist_range = llvm::iterator_range<clauselist_iterator>;
385 using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
387 unsigned clauselist_size() const { return NumClauses; }
388 bool clauselist_empty() const { return NumClauses == 0; }
390 clauselist_range clauselists() {
391 return clauselist_range(clauselist_begin(), clauselist_end());
393 clauselist_const_range clauselists() const {
394 return clauselist_const_range(clauselist_begin(), clauselist_end());
396 clauselist_iterator clauselist_begin() { return getClauses().begin(); }
397 clauselist_iterator clauselist_end() { return getClauses().end(); }
398 clauselist_const_iterator clauselist_begin() const {
399 return getClauses().begin();
401 clauselist_const_iterator clauselist_end() const {
402 return getClauses().end();
405 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
406 static bool classofKind(Kind K) { return K == OMPRequires; }
409 /// This represents '#pragma omp allocate ...' directive.
410 /// For example, in the following, the default allocator is used for both 'a'
415 /// #pragma omp allocate(a)
418 /// #pragma omp allocate(b)
422 class OMPAllocateDecl final
424 private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> {
425 friend class ASTDeclReader;
426 friend TrailingObjects;
428 /// Number of variable within the allocate directive.
429 unsigned NumVars = 0;
430 /// Number of clauses associated with the allocate directive.
431 unsigned NumClauses = 0;
433 size_t numTrailingObjects(OverloadToken<Expr *>) const {
436 size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
440 virtual void anchor();
442 OMPAllocateDecl(Kind DK, DeclContext *DC, SourceLocation L)
445 ArrayRef<const Expr *> getVars() const {
446 return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
449 MutableArrayRef<Expr *> getVars() {
450 return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
453 void setVars(ArrayRef<Expr *> VL);
455 /// Returns an array of immutable clauses associated with this directive.
456 ArrayRef<OMPClause *> getClauses() const {
457 return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
460 /// Returns an array of clauses associated with this directive.
461 MutableArrayRef<OMPClause *> getClauses() {
462 return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
466 /// Sets an array of clauses to this requires declaration
467 void setClauses(ArrayRef<OMPClause *> CL);
470 static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
471 SourceLocation L, ArrayRef<Expr *> VL,
472 ArrayRef<OMPClause *> CL);
473 static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
474 unsigned NVars, unsigned NClauses);
476 typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
477 typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
478 typedef llvm::iterator_range<varlist_iterator> varlist_range;
479 typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
480 using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
481 using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
482 using clauselist_range = llvm::iterator_range<clauselist_iterator>;
483 using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
486 unsigned varlist_size() const { return NumVars; }
487 bool varlist_empty() const { return NumVars == 0; }
488 unsigned clauselist_size() const { return NumClauses; }
489 bool clauselist_empty() const { return NumClauses == 0; }
491 varlist_range varlists() {
492 return varlist_range(varlist_begin(), varlist_end());
494 varlist_const_range varlists() const {
495 return varlist_const_range(varlist_begin(), varlist_end());
497 varlist_iterator varlist_begin() { return getVars().begin(); }
498 varlist_iterator varlist_end() { return getVars().end(); }
499 varlist_const_iterator varlist_begin() const { return getVars().begin(); }
500 varlist_const_iterator varlist_end() const { return getVars().end(); }
502 clauselist_range clauselists() {
503 return clauselist_range(clauselist_begin(), clauselist_end());
505 clauselist_const_range clauselists() const {
506 return clauselist_const_range(clauselist_begin(), clauselist_end());
508 clauselist_iterator clauselist_begin() { return getClauses().begin(); }
509 clauselist_iterator clauselist_end() { return getClauses().end(); }
510 clauselist_const_iterator clauselist_begin() const {
511 return getClauses().begin();
513 clauselist_const_iterator clauselist_end() const {
514 return getClauses().end();
517 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
518 static bool classofKind(Kind K) { return K == OMPAllocate; }
521 } // end namespace clang