xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-==//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file defines OpenMP nodes for declarative directives.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_DECLOPENMP_H
15 #define LLVM_CLANG_AST_DECLOPENMP_H
16 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExternalASTSource.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/Type.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/Support/TrailingObjects.h"
25 
26 namespace clang {
27 
28 /// This is a basic class for representing single OpenMP declarative directive.
29 ///
30 template <typename U> class OMPDeclarativeDirective : public U {
31   friend class ASTDeclReader;
32   friend class ASTDeclWriter;
33 
34   /// Get the clauses storage.
getClauses()35   MutableArrayRef<OMPClause *> getClauses() {
36     if (!Data)
37       return std::nullopt;
38     return Data->getClauses();
39   }
40 
41 protected:
42   /// Data, associated with the directive.
43   OMPChildren *Data = nullptr;
44 
45   /// Build instance of directive.
46   template <typename... Params>
OMPDeclarativeDirective(Params &&...P)47   OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
48 
49   template <typename T, typename... Params>
createDirective(const ASTContext & C,DeclContext * DC,ArrayRef<OMPClause * > Clauses,unsigned NumChildren,Params &&...P)50   static T *createDirective(const ASTContext &C, DeclContext *DC,
51                             ArrayRef<OMPClause *> Clauses, unsigned NumChildren,
52                             Params &&... P) {
53     auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
54         T(DC, std::forward<Params>(P)...);
55     Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
56                                      /*AssociatedStmt=*/nullptr, NumChildren);
57     Inst->Data->setClauses(Clauses);
58     return Inst;
59   }
60 
61   template <typename T, typename... Params>
createEmptyDirective(const ASTContext & C,GlobalDeclID ID,unsigned NumClauses,unsigned NumChildren,Params &&...P)62   static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID,
63                                  unsigned NumClauses, unsigned NumChildren,
64                                  Params &&... P) {
65     auto *Inst = new (C, ID, size(NumClauses, NumChildren))
66         T(nullptr, std::forward<Params>(P)...);
67     Inst->Data = OMPChildren::CreateEmpty(
68         Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
69     return Inst;
70   }
71 
size(unsigned NumClauses,unsigned NumChildren)72   static size_t size(unsigned NumClauses, unsigned NumChildren) {
73     return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
74                              NumChildren);
75   }
76 
77 public:
78   /// Get number of clauses.
getNumClauses()79   unsigned getNumClauses() const {
80     if (!Data)
81       return 0;
82     return Data->getNumClauses();
83   }
84 
85   /// Returns specified clause.
86   ///
87   /// \param I Number of clause.
88   ///
getClause(unsigned I)89   OMPClause *getClause(unsigned I) const { return clauses()[I]; }
90 
clauses()91   ArrayRef<OMPClause *> clauses() const {
92     if (!Data)
93       return std::nullopt;
94     return Data->getClauses();
95   }
96 };
97 
98 /// This represents '#pragma omp threadprivate ...' directive.
99 /// For example, in the following, both 'a' and 'A::b' are threadprivate:
100 ///
101 /// \code
102 /// int a;
103 /// #pragma omp threadprivate(a)
104 /// struct A {
105 ///   static int b;
106 /// #pragma omp threadprivate(b)
107 /// };
108 /// \endcode
109 ///
110 class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
111   friend class OMPDeclarativeDirective<Decl>;
112 
113   virtual void anchor();
114 
115   OMPThreadPrivateDecl(DeclContext *DC = nullptr,
116                        SourceLocation L = SourceLocation())
117       : OMPDeclarativeDirective<Decl>(OMPThreadPrivate, DC, L) {}
118 
getVars()119   ArrayRef<const Expr *> getVars() const {
120     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
121     return llvm::ArrayRef(Storage, Data->getNumChildren());
122   }
123 
getVars()124   MutableArrayRef<Expr *> getVars() {
125     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
126     return llvm::MutableArrayRef(Storage, Data->getNumChildren());
127   }
128 
129   void setVars(ArrayRef<Expr *> VL);
130 
131 public:
132   static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
133                                       SourceLocation L,
134                                       ArrayRef<Expr *> VL);
135   static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
136                                                   GlobalDeclID ID, unsigned N);
137 
138   typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
139   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
140   typedef llvm::iterator_range<varlist_iterator> varlist_range;
141   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
142 
varlist_size()143   unsigned varlist_size() const { return Data->getNumChildren(); }
varlist_empty()144   bool varlist_empty() const { return Data->getChildren().empty(); }
145 
varlists()146   varlist_range varlists() {
147     return varlist_range(varlist_begin(), varlist_end());
148   }
varlists()149   varlist_const_range varlists() const {
150     return varlist_const_range(varlist_begin(), varlist_end());
151   }
varlist_begin()152   varlist_iterator varlist_begin() { return getVars().begin(); }
varlist_end()153   varlist_iterator varlist_end() { return getVars().end(); }
varlist_begin()154   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
varlist_end()155   varlist_const_iterator varlist_end() const { return getVars().end(); }
156 
classof(const Decl * D)157   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)158   static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
159 };
160 
161 enum class OMPDeclareReductionInitKind {
162   Call,   // Initialized by function call.
163   Direct, // omp_priv(<expr>)
164   Copy    // omp_priv = <expr>
165 };
166 
167 /// This represents '#pragma omp declare reduction ...' directive.
168 /// For example, in the following, declared reduction 'foo' for types 'int' and
169 /// 'float':
170 ///
171 /// \code
172 /// #pragma omp declare reduction (foo : int,float : omp_out += omp_in)
173 ///                     initializer (omp_priv = 0)
174 /// \endcode
175 ///
176 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
177 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
178   // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
179   // to save some space. Use the provided accessors to access it.
180 
181   friend class ASTDeclReader;
182   /// Combiner for declare reduction construct.
183   Expr *Combiner = nullptr;
184   /// Initializer for declare reduction construct.
185   Expr *Initializer = nullptr;
186   /// In parameter of the combiner.
187   Expr *In = nullptr;
188   /// Out parameter of the combiner.
189   Expr *Out = nullptr;
190   /// Priv parameter of the initializer.
191   Expr *Priv = nullptr;
192   /// Orig parameter of the initializer.
193   Expr *Orig = nullptr;
194 
195   /// Reference to the previous declare reduction construct in the same
196   /// scope with the same name. Required for proper templates instantiation if
197   /// the declare reduction construct is declared inside compound statement.
198   LazyDeclPtr PrevDeclInScope;
199 
200   void anchor() override;
201 
202   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
203                           DeclarationName Name, QualType Ty,
204                           OMPDeclareReductionDecl *PrevDeclInScope);
205 
setPrevDeclInScope(OMPDeclareReductionDecl * Prev)206   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
207     PrevDeclInScope = Prev;
208   }
209 
210 public:
211   /// Create declare reduction node.
212   static OMPDeclareReductionDecl *
213   Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
214          QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
215   /// Create deserialized declare reduction node.
216   static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
217                                                      GlobalDeclID ID);
218 
219   /// Get combiner expression of the declare reduction construct.
getCombiner()220   Expr *getCombiner() { return Combiner; }
getCombiner()221   const Expr *getCombiner() const { return Combiner; }
222   /// Get In variable of the combiner.
getCombinerIn()223   Expr *getCombinerIn() { return In; }
getCombinerIn()224   const Expr *getCombinerIn() const { return In; }
225   /// Get Out variable of the combiner.
getCombinerOut()226   Expr *getCombinerOut() { return Out; }
getCombinerOut()227   const Expr *getCombinerOut() const { return Out; }
228   /// Set combiner expression for the declare reduction construct.
setCombiner(Expr * E)229   void setCombiner(Expr *E) { Combiner = E; }
230   /// Set combiner In and Out vars.
setCombinerData(Expr * InE,Expr * OutE)231   void setCombinerData(Expr *InE, Expr *OutE) {
232     In = InE;
233     Out = OutE;
234   }
235 
236   /// Get initializer expression (if specified) of the declare reduction
237   /// construct.
getInitializer()238   Expr *getInitializer() { return Initializer; }
getInitializer()239   const Expr *getInitializer() const { return Initializer; }
240   /// Get initializer kind.
getInitializerKind()241   OMPDeclareReductionInitKind getInitializerKind() const {
242     return static_cast<OMPDeclareReductionInitKind>(
243         OMPDeclareReductionDeclBits.InitializerKind);
244   }
245   /// Get Orig variable of the initializer.
getInitOrig()246   Expr *getInitOrig() { return Orig; }
getInitOrig()247   const Expr *getInitOrig() const { return Orig; }
248   /// Get Priv variable of the initializer.
getInitPriv()249   Expr *getInitPriv() { return Priv; }
getInitPriv()250   const Expr *getInitPriv() const { return Priv; }
251   /// Set initializer expression for the declare reduction construct.
setInitializer(Expr * E,OMPDeclareReductionInitKind IK)252   void setInitializer(Expr *E, OMPDeclareReductionInitKind IK) {
253     Initializer = E;
254     OMPDeclareReductionDeclBits.InitializerKind = llvm::to_underlying(IK);
255   }
256   /// Set initializer Orig and Priv vars.
setInitializerData(Expr * OrigE,Expr * PrivE)257   void setInitializerData(Expr *OrigE, Expr *PrivE) {
258     Orig = OrigE;
259     Priv = PrivE;
260   }
261 
262   /// Get reference to previous declare reduction construct in the same
263   /// scope with the same name.
264   OMPDeclareReductionDecl *getPrevDeclInScope();
265   const OMPDeclareReductionDecl *getPrevDeclInScope() const;
266 
classof(const Decl * D)267   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)268   static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
castToDeclContext(const OMPDeclareReductionDecl * D)269   static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
270     return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
271   }
castFromDeclContext(const DeclContext * DC)272   static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) {
273     return static_cast<OMPDeclareReductionDecl *>(
274         const_cast<DeclContext *>(DC));
275   }
276 };
277 
278 /// This represents '#pragma omp declare mapper ...' directive. Map clauses are
279 /// allowed to use with this directive. The following example declares a user
280 /// defined mapper for the type 'struct vec'. This example instructs the fields
281 /// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.
282 ///
283 /// \code
284 /// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
285 /// \endcode
286 class OMPDeclareMapperDecl final : public OMPDeclarativeDirective<ValueDecl>,
287                                    public DeclContext {
288   friend class OMPDeclarativeDirective<ValueDecl>;
289   friend class ASTDeclReader;
290   friend class ASTDeclWriter;
291 
292   /// Mapper variable, which is 'v' in the example above
293   Expr *MapperVarRef = nullptr;
294 
295   /// Name of the mapper variable
296   DeclarationName VarName;
297 
298   LazyDeclPtr PrevDeclInScope;
299 
300   void anchor() override;
301 
OMPDeclareMapperDecl(DeclContext * DC,SourceLocation L,DeclarationName Name,QualType Ty,DeclarationName VarName,OMPDeclareMapperDecl * PrevDeclInScope)302   OMPDeclareMapperDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
303                        QualType Ty, DeclarationName VarName,
304                        OMPDeclareMapperDecl *PrevDeclInScope)
305       : OMPDeclarativeDirective<ValueDecl>(OMPDeclareMapper, DC, L, Name, Ty),
306         DeclContext(OMPDeclareMapper), VarName(VarName),
307         PrevDeclInScope(PrevDeclInScope) {}
308 
setPrevDeclInScope(OMPDeclareMapperDecl * Prev)309   void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
310     PrevDeclInScope = Prev;
311   }
312 
313 public:
314   /// Creates declare mapper node.
315   static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
316                                       SourceLocation L, DeclarationName Name,
317                                       QualType T, DeclarationName VarName,
318                                       ArrayRef<OMPClause *> Clauses,
319                                       OMPDeclareMapperDecl *PrevDeclInScope);
320   /// Creates deserialized declare mapper node.
321   static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C,
322                                                   GlobalDeclID ID, unsigned N);
323 
324   using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
325   using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
326   using clauselist_range = llvm::iterator_range<clauselist_iterator>;
327   using clauselist_const_range =
328       llvm::iterator_range<clauselist_const_iterator>;
329 
clauselist_size()330   unsigned clauselist_size() const { return Data->getNumClauses(); }
clauselist_empty()331   bool clauselist_empty() const { return Data->getClauses().empty(); }
332 
clauselists()333   clauselist_range clauselists() {
334     return clauselist_range(clauselist_begin(), clauselist_end());
335   }
clauselists()336   clauselist_const_range clauselists() const {
337     return clauselist_const_range(clauselist_begin(), clauselist_end());
338   }
clauselist_begin()339   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_end()340   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_begin()341   clauselist_const_iterator clauselist_begin() const {
342     return Data->getClauses().begin();
343   }
clauselist_end()344   clauselist_const_iterator clauselist_end() const {
345     return Data->getClauses().end();
346   }
347 
348   /// Get the variable declared in the mapper
getMapperVarRef()349   Expr *getMapperVarRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
getMapperVarRef()350   const Expr *getMapperVarRef() const {
351     return cast_or_null<Expr>(Data->getChildren()[0]);
352   }
353   /// Set the variable declared in the mapper
setMapperVarRef(Expr * MapperVarRefE)354   void setMapperVarRef(Expr *MapperVarRefE) {
355     Data->getChildren()[0] = MapperVarRefE;
356   }
357 
358   /// Get the name of the variable declared in the mapper
getVarName()359   DeclarationName getVarName() { return VarName; }
360 
361   /// Get reference to previous declare mapper construct in the same
362   /// scope with the same name.
363   OMPDeclareMapperDecl *getPrevDeclInScope();
364   const OMPDeclareMapperDecl *getPrevDeclInScope() const;
365 
classof(const Decl * D)366   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)367   static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
castToDeclContext(const OMPDeclareMapperDecl * D)368   static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
369     return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
370   }
castFromDeclContext(const DeclContext * DC)371   static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {
372     return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));
373   }
374 };
375 
376 /// Pseudo declaration for capturing expressions. Also is used for capturing of
377 /// non-static data members in non-static member functions.
378 ///
379 /// Clang supports capturing of variables only, but OpenMP 4.5 allows to
380 /// privatize non-static members of current class in non-static member
381 /// functions. This pseudo-declaration allows properly handle this kind of
382 /// capture by wrapping captured expression into a variable-like declaration.
383 class OMPCapturedExprDecl final : public VarDecl {
384   friend class ASTDeclReader;
385   void anchor() override;
386 
OMPCapturedExprDecl(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,QualType Type,TypeSourceInfo * TInfo,SourceLocation StartLoc)387   OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
388                       QualType Type, TypeSourceInfo *TInfo,
389                       SourceLocation StartLoc)
390       : VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
391                 SC_None) {
392     setImplicit();
393   }
394 
395 public:
396   static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC,
397                                      IdentifierInfo *Id, QualType T,
398                                      SourceLocation StartLoc);
399 
400   static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C,
401                                                  GlobalDeclID ID);
402 
403   SourceRange getSourceRange() const override LLVM_READONLY;
404 
405   // Implement isa/cast/dyncast/etc.
classof(const Decl * D)406   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)407   static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
408 };
409 
410 /// This represents '#pragma omp requires...' directive.
411 /// For example
412 ///
413 /// \code
414 /// #pragma omp requires unified_address
415 /// \endcode
416 ///
417 class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
418   friend class OMPDeclarativeDirective<Decl>;
419   friend class ASTDeclReader;
420 
421   virtual void anchor();
422 
OMPRequiresDecl(DeclContext * DC,SourceLocation L)423   OMPRequiresDecl(DeclContext *DC, SourceLocation L)
424       : OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}
425 
426 public:
427   /// Create requires node.
428   static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
429                                  SourceLocation L, ArrayRef<OMPClause *> CL);
430   /// Create deserialized requires node.
431   static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
432                                              unsigned N);
433 
434   using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
435   using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
436   using clauselist_range = llvm::iterator_range<clauselist_iterator>;
437   using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
438 
clauselist_size()439   unsigned clauselist_size() const { return Data->getNumClauses(); }
clauselist_empty()440   bool clauselist_empty() const { return Data->getClauses().empty(); }
441 
clauselists()442   clauselist_range clauselists() {
443     return clauselist_range(clauselist_begin(), clauselist_end());
444   }
clauselists()445   clauselist_const_range clauselists() const {
446     return clauselist_const_range(clauselist_begin(), clauselist_end());
447   }
clauselist_begin()448   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_end()449   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_begin()450   clauselist_const_iterator clauselist_begin() const {
451     return Data->getClauses().begin();
452   }
clauselist_end()453   clauselist_const_iterator clauselist_end() const {
454     return Data->getClauses().end();
455   }
456 
classof(const Decl * D)457   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)458   static bool classofKind(Kind K) { return K == OMPRequires; }
459 };
460 
461 /// This represents '#pragma omp allocate ...' directive.
462 /// For example, in the following, the default allocator is used for both 'a'
463 /// and 'A::b':
464 ///
465 /// \code
466 /// int a;
467 /// #pragma omp allocate(a)
468 /// struct A {
469 ///   static int b;
470 /// #pragma omp allocate(b)
471 /// };
472 /// \endcode
473 ///
474 class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
475   friend class OMPDeclarativeDirective<Decl>;
476   friend class ASTDeclReader;
477 
478   virtual void anchor();
479 
OMPAllocateDecl(DeclContext * DC,SourceLocation L)480   OMPAllocateDecl(DeclContext *DC, SourceLocation L)
481       : OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}
482 
getVars()483   ArrayRef<const Expr *> getVars() const {
484     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
485     return llvm::ArrayRef(Storage, Data->getNumChildren());
486   }
487 
getVars()488   MutableArrayRef<Expr *> getVars() {
489     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
490     return llvm::MutableArrayRef(Storage, Data->getNumChildren());
491   }
492 
493   void setVars(ArrayRef<Expr *> VL);
494 
495 public:
496   static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
497                                  SourceLocation L, ArrayRef<Expr *> VL,
498                                  ArrayRef<OMPClause *> CL);
499   static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
500                                              unsigned NVars, unsigned NClauses);
501 
502   typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
503   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
504   typedef llvm::iterator_range<varlist_iterator> varlist_range;
505   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
506   using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
507   using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
508   using clauselist_range = llvm::iterator_range<clauselist_iterator>;
509   using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
510 
varlist_size()511   unsigned varlist_size() const { return Data->getNumChildren(); }
varlist_empty()512   bool varlist_empty() const { return Data->getChildren().empty(); }
clauselist_size()513   unsigned clauselist_size() const { return Data->getNumClauses(); }
clauselist_empty()514   bool clauselist_empty() const { return Data->getClauses().empty(); }
515 
varlists()516   varlist_range varlists() {
517     return varlist_range(varlist_begin(), varlist_end());
518   }
varlists()519   varlist_const_range varlists() const {
520     return varlist_const_range(varlist_begin(), varlist_end());
521   }
varlist_begin()522   varlist_iterator varlist_begin() { return getVars().begin(); }
varlist_end()523   varlist_iterator varlist_end() { return getVars().end(); }
varlist_begin()524   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
varlist_end()525   varlist_const_iterator varlist_end() const { return getVars().end(); }
526 
clauselists()527   clauselist_range clauselists() {
528     return clauselist_range(clauselist_begin(), clauselist_end());
529   }
clauselists()530   clauselist_const_range clauselists() const {
531     return clauselist_const_range(clauselist_begin(), clauselist_end());
532   }
clauselist_begin()533   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_end()534   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_begin()535   clauselist_const_iterator clauselist_begin() const {
536     return Data->getClauses().begin();
537   }
clauselist_end()538   clauselist_const_iterator clauselist_end() const {
539     return Data->getClauses().end();
540   }
541 
classof(const Decl * D)542   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
classofKind(Kind K)543   static bool classofKind(Kind K) { return K == OMPAllocate; }
544 };
545 
546 } // end namespace clang
547 
548 #endif
549