DeclOpenMP.h 21 KB

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