Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.
  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>
  47.   OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
  48.  
  49.   template <typename T, typename... Params>
  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>
  62.   static T *createEmptyDirective(const ASTContext &C, unsigned 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.  
  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.
  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.   ///
  89.   OMPClause *getClause(unsigned I) const { return clauses()[I]; }
  90.  
  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.  
  119.   ArrayRef<const Expr *> getVars() const {
  120.     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
  121.     return llvm::ArrayRef(Storage, Data->getNumChildren());
  122.   }
  123.  
  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.                                                   unsigned 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.  
  143.   unsigned varlist_size() const { return Data->getNumChildren(); }
  144.   bool varlist_empty() const { return Data->getChildren().empty(); }
  145.  
  146.   varlist_range varlists() {
  147.     return varlist_range(varlist_begin(), varlist_end());
  148.   }
  149.   varlist_const_range varlists() const {
  150.     return varlist_const_range(varlist_begin(), varlist_end());
  151.   }
  152.   varlist_iterator varlist_begin() { return getVars().begin(); }
  153.   varlist_iterator varlist_end() { return getVars().end(); }
  154.   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
  155.   varlist_const_iterator varlist_end() const { return getVars().end(); }
  156.  
  157.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  158.   static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
  159. };
  160.  
  161. /// This represents '#pragma omp declare reduction ...' directive.
  162. /// For example, in the following, declared reduction 'foo' for types 'int' and
  163. /// 'float':
  164. ///
  165. /// \code
  166. /// #pragma omp declare reduction (foo : int,float : omp_out += omp_in)
  167. ///                     initializer (omp_priv = 0)
  168. /// \endcode
  169. ///
  170. /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
  171. class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
  172.   // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
  173.   // to save some space. Use the provided accessors to access it.
  174. public:
  175.   enum InitKind {
  176.     CallInit,   // Initialized by function call.
  177.     DirectInit, // omp_priv(<expr>)
  178.     CopyInit    // omp_priv = <expr>
  179.   };
  180.  
  181. private:
  182.   friend class ASTDeclReader;
  183.   /// Combiner for declare reduction construct.
  184.   Expr *Combiner = nullptr;
  185.   /// Initializer for declare reduction construct.
  186.   Expr *Initializer = nullptr;
  187.   /// In parameter of the combiner.
  188.   Expr *In = nullptr;
  189.   /// Out parameter of the combiner.
  190.   Expr *Out = nullptr;
  191.   /// Priv parameter of the initializer.
  192.   Expr *Priv = nullptr;
  193.   /// Orig parameter of the initializer.
  194.   Expr *Orig = nullptr;
  195.  
  196.   /// Reference to the previous declare reduction construct in the same
  197.   /// scope with the same name. Required for proper templates instantiation if
  198.   /// the declare reduction construct is declared inside compound statement.
  199.   LazyDeclPtr PrevDeclInScope;
  200.  
  201.   void anchor() override;
  202.  
  203.   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
  204.                           DeclarationName Name, QualType Ty,
  205.                           OMPDeclareReductionDecl *PrevDeclInScope);
  206.  
  207.   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
  208.     PrevDeclInScope = Prev;
  209.   }
  210.  
  211. public:
  212.   /// Create declare reduction node.
  213.   static OMPDeclareReductionDecl *
  214.   Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
  215.          QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
  216.   /// Create deserialized declare reduction node.
  217.   static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
  218.                                                      unsigned ID);
  219.  
  220.   /// Get combiner expression of the declare reduction construct.
  221.   Expr *getCombiner() { return Combiner; }
  222.   const Expr *getCombiner() const { return Combiner; }
  223.   /// Get In variable of the combiner.
  224.   Expr *getCombinerIn() { return In; }
  225.   const Expr *getCombinerIn() const { return In; }
  226.   /// Get Out variable of the combiner.
  227.   Expr *getCombinerOut() { return Out; }
  228.   const Expr *getCombinerOut() const { return Out; }
  229.   /// Set combiner expression for the declare reduction construct.
  230.   void setCombiner(Expr *E) { Combiner = E; }
  231.   /// Set combiner In and Out vars.
  232.   void setCombinerData(Expr *InE, Expr *OutE) {
  233.     In = InE;
  234.     Out = OutE;
  235.   }
  236.  
  237.   /// Get initializer expression (if specified) of the declare reduction
  238.   /// construct.
  239.   Expr *getInitializer() { return Initializer; }
  240.   const Expr *getInitializer() const { return Initializer; }
  241.   /// Get initializer kind.
  242.   InitKind getInitializerKind() const {
  243.     return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
  244.   }
  245.   /// Get Orig variable of the initializer.
  246.   Expr *getInitOrig() { return Orig; }
  247.   const Expr *getInitOrig() const { return Orig; }
  248.   /// Get Priv variable of the initializer.
  249.   Expr *getInitPriv() { return Priv; }
  250.   const Expr *getInitPriv() const { return Priv; }
  251.   /// Set initializer expression for the declare reduction construct.
  252.   void setInitializer(Expr *E, InitKind IK) {
  253.     Initializer = E;
  254.     OMPDeclareReductionDeclBits.InitializerKind = IK;
  255.   }
  256.   /// Set initializer Orig and Priv vars.
  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.  
  267.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  268.   static bool classofKind(Kind K) { return K == OMPDeclareReduction; }
  269.   static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) {
  270.     return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D));
  271.   }
  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.  
  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.  
  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, unsigned ID,
  322.                                                   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.  
  330.   unsigned clauselist_size() const { return Data->getNumClauses(); }
  331.   bool clauselist_empty() const { return Data->getClauses().empty(); }
  332.  
  333.   clauselist_range clauselists() {
  334.     return clauselist_range(clauselist_begin(), clauselist_end());
  335.   }
  336.   clauselist_const_range clauselists() const {
  337.     return clauselist_const_range(clauselist_begin(), clauselist_end());
  338.   }
  339.   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  340.   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  341.   clauselist_const_iterator clauselist_begin() const {
  342.     return Data->getClauses().begin();
  343.   }
  344.   clauselist_const_iterator clauselist_end() const {
  345.     return Data->getClauses().end();
  346.   }
  347.  
  348.   /// Get the variable declared in the mapper
  349.   Expr *getMapperVarRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
  350.   const Expr *getMapperVarRef() const {
  351.     return cast_or_null<Expr>(Data->getChildren()[0]);
  352.   }
  353.   /// Set the variable declared in the mapper
  354.   void setMapperVarRef(Expr *MapperVarRefE) {
  355.     Data->getChildren()[0] = MapperVarRefE;
  356.   }
  357.  
  358.   /// Get the name of the variable declared in the mapper
  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.  
  366.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  367.   static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
  368.   static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
  369.     return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
  370.   }
  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.  
  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, unsigned ID);
  401.  
  402.   SourceRange getSourceRange() const override LLVM_READONLY;
  403.  
  404.   // Implement isa/cast/dyncast/etc.
  405.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  406.   static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
  407. };
  408.  
  409. /// This represents '#pragma omp requires...' directive.
  410. /// For example
  411. ///
  412. /// \code
  413. /// #pragma omp requires unified_address
  414. /// \endcode
  415. ///
  416. class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
  417.   friend class OMPDeclarativeDirective<Decl>;
  418.   friend class ASTDeclReader;
  419.  
  420.   virtual void anchor();
  421.  
  422.   OMPRequiresDecl(DeclContext *DC, SourceLocation L)
  423.       : OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}
  424.  
  425. public:
  426.   /// Create requires node.
  427.   static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
  428.                                  SourceLocation L, ArrayRef<OMPClause *> CL);
  429.   /// Create deserialized requires node.
  430.   static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
  431.                                              unsigned N);
  432.  
  433.   using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
  434.   using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
  435.   using clauselist_range = llvm::iterator_range<clauselist_iterator>;
  436.   using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
  437.  
  438.   unsigned clauselist_size() const { return Data->getNumClauses(); }
  439.   bool clauselist_empty() const { return Data->getClauses().empty(); }
  440.  
  441.   clauselist_range clauselists() {
  442.     return clauselist_range(clauselist_begin(), clauselist_end());
  443.   }
  444.   clauselist_const_range clauselists() const {
  445.     return clauselist_const_range(clauselist_begin(), clauselist_end());
  446.   }
  447.   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  448.   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  449.   clauselist_const_iterator clauselist_begin() const {
  450.     return Data->getClauses().begin();
  451.   }
  452.   clauselist_const_iterator clauselist_end() const {
  453.     return Data->getClauses().end();
  454.   }
  455.  
  456.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  457.   static bool classofKind(Kind K) { return K == OMPRequires; }
  458. };
  459.  
  460. /// This represents '#pragma omp allocate ...' directive.
  461. /// For example, in the following, the default allocator is used for both 'a'
  462. /// and 'A::b':
  463. ///
  464. /// \code
  465. /// int a;
  466. /// #pragma omp allocate(a)
  467. /// struct A {
  468. ///   static int b;
  469. /// #pragma omp allocate(b)
  470. /// };
  471. /// \endcode
  472. ///
  473. class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
  474.   friend class OMPDeclarativeDirective<Decl>;
  475.   friend class ASTDeclReader;
  476.  
  477.   virtual void anchor();
  478.  
  479.   OMPAllocateDecl(DeclContext *DC, SourceLocation L)
  480.       : OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}
  481.  
  482.   ArrayRef<const Expr *> getVars() const {
  483.     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
  484.     return llvm::ArrayRef(Storage, Data->getNumChildren());
  485.   }
  486.  
  487.   MutableArrayRef<Expr *> getVars() {
  488.     auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
  489.     return llvm::MutableArrayRef(Storage, Data->getNumChildren());
  490.   }
  491.  
  492.   void setVars(ArrayRef<Expr *> VL);
  493.  
  494. public:
  495.   static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
  496.                                  SourceLocation L, ArrayRef<Expr *> VL,
  497.                                  ArrayRef<OMPClause *> CL);
  498.   static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
  499.                                              unsigned NVars, unsigned NClauses);
  500.  
  501.   typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
  502.   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
  503.   typedef llvm::iterator_range<varlist_iterator> varlist_range;
  504.   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
  505.   using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
  506.   using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
  507.   using clauselist_range = llvm::iterator_range<clauselist_iterator>;
  508.   using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
  509.  
  510.   unsigned varlist_size() const { return Data->getNumChildren(); }
  511.   bool varlist_empty() const { return Data->getChildren().empty(); }
  512.   unsigned clauselist_size() const { return Data->getNumClauses(); }
  513.   bool clauselist_empty() const { return Data->getClauses().empty(); }
  514.  
  515.   varlist_range varlists() {
  516.     return varlist_range(varlist_begin(), varlist_end());
  517.   }
  518.   varlist_const_range varlists() const {
  519.     return varlist_const_range(varlist_begin(), varlist_end());
  520.   }
  521.   varlist_iterator varlist_begin() { return getVars().begin(); }
  522.   varlist_iterator varlist_end() { return getVars().end(); }
  523.   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
  524.   varlist_const_iterator varlist_end() const { return getVars().end(); }
  525.  
  526.   clauselist_range clauselists() {
  527.     return clauselist_range(clauselist_begin(), clauselist_end());
  528.   }
  529.   clauselist_const_range clauselists() const {
  530.     return clauselist_const_range(clauselist_begin(), clauselist_end());
  531.   }
  532.   clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
  533.   clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
  534.   clauselist_const_iterator clauselist_begin() const {
  535.     return Data->getClauses().begin();
  536.   }
  537.   clauselist_const_iterator clauselist_end() const {
  538.     return Data->getClauses().end();
  539.   }
  540.  
  541.   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
  542.   static bool classofKind(Kind K) { return K == OMPAllocate; }
  543. };
  544.  
  545. } // end namespace clang
  546.  
  547. #endif
  548.