ExprOpenMP.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- ExprOpenMP.h - Classes for representing expressions ----*- 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. // This file defines the Expr interface and subclasses.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_AST_EXPROPENMP_H
  18. #define LLVM_CLANG_AST_EXPROPENMP_H
  19. #include "clang/AST/ComputeDependence.h"
  20. #include "clang/AST/Expr.h"
  21. namespace clang {
  22. /// OpenMP 5.0 [2.1.5, Array Sections].
  23. /// To specify an array section in an OpenMP construct, array subscript
  24. /// expressions are extended with the following syntax:
  25. /// \code
  26. /// [ lower-bound : length : stride ]
  27. /// [ lower-bound : length : ]
  28. /// [ lower-bound : length ]
  29. /// [ lower-bound : : stride ]
  30. /// [ lower-bound : : ]
  31. /// [ lower-bound : ]
  32. /// [ : length : stride ]
  33. /// [ : length : ]
  34. /// [ : length ]
  35. /// [ : : stride ]
  36. /// [ : : ]
  37. /// [ : ]
  38. /// \endcode
  39. /// The array section must be a subset of the original array.
  40. /// Array sections are allowed on multidimensional arrays. Base language array
  41. /// subscript expressions can be used to specify length-one dimensions of
  42. /// multidimensional array sections.
  43. /// Each of the lower-bound, length, and stride expressions if specified must be
  44. /// an integral type expressions of the base language. When evaluated
  45. /// they represent a set of integer values as follows:
  46. /// \code
  47. /// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
  48. /// lower-bound + ((length - 1) * stride) }
  49. /// \endcode
  50. /// The lower-bound and length must evaluate to non-negative integers.
  51. /// The stride must evaluate to a positive integer.
  52. /// When the size of the array dimension is not known, the length must be
  53. /// specified explicitly.
  54. /// When the stride is absent it defaults to 1.
  55. /// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
  56. /// where size is the size of the array dimension. When the lower-bound is
  57. /// absent it defaults to 0.
  58. class OMPArraySectionExpr : public Expr {
  59. enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
  60. Stmt *SubExprs[END_EXPR];
  61. SourceLocation ColonLocFirst;
  62. SourceLocation ColonLocSecond;
  63. SourceLocation RBracketLoc;
  64. public:
  65. OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
  66. QualType Type, ExprValueKind VK, ExprObjectKind OK,
  67. SourceLocation ColonLocFirst,
  68. SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
  69. : Expr(OMPArraySectionExprClass, Type, VK, OK),
  70. ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
  71. RBracketLoc(RBracketLoc) {
  72. SubExprs[BASE] = Base;
  73. SubExprs[LOWER_BOUND] = LowerBound;
  74. SubExprs[LENGTH] = Length;
  75. SubExprs[STRIDE] = Stride;
  76. setDependence(computeDependence(this));
  77. }
  78. /// Create an empty array section expression.
  79. explicit OMPArraySectionExpr(EmptyShell Shell)
  80. : Expr(OMPArraySectionExprClass, Shell) {}
  81. /// An array section can be written only as Base[LowerBound:Length].
  82. /// Get base of the array section.
  83. Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
  84. const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
  85. /// Set base of the array section.
  86. void setBase(Expr *E) { SubExprs[BASE] = E; }
  87. /// Return original type of the base expression for array section.
  88. static QualType getBaseOriginalType(const Expr *Base);
  89. /// Get lower bound of array section.
  90. Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
  91. const Expr *getLowerBound() const {
  92. return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
  93. }
  94. /// Set lower bound of the array section.
  95. void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
  96. /// Get length of array section.
  97. Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
  98. const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
  99. /// Set length of the array section.
  100. void setLength(Expr *E) { SubExprs[LENGTH] = E; }
  101. /// Get stride of array section.
  102. Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); }
  103. const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); }
  104. /// Set length of the array section.
  105. void setStride(Expr *E) { SubExprs[STRIDE] = E; }
  106. SourceLocation getBeginLoc() const LLVM_READONLY {
  107. return getBase()->getBeginLoc();
  108. }
  109. SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
  110. SourceLocation getColonLocFirst() const { return ColonLocFirst; }
  111. void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
  112. SourceLocation getColonLocSecond() const { return ColonLocSecond; }
  113. void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }
  114. SourceLocation getRBracketLoc() const { return RBracketLoc; }
  115. void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
  116. SourceLocation getExprLoc() const LLVM_READONLY {
  117. return getBase()->getExprLoc();
  118. }
  119. static bool classof(const Stmt *T) {
  120. return T->getStmtClass() == OMPArraySectionExprClass;
  121. }
  122. child_range children() {
  123. return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
  124. }
  125. const_child_range children() const {
  126. return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
  127. }
  128. };
  129. /// An explicit cast in C or a C-style cast in C++, which uses the syntax
  130. /// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
  131. class OMPArrayShapingExpr final
  132. : public Expr,
  133. private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
  134. friend TrailingObjects;
  135. friend class ASTStmtReader;
  136. friend class ASTStmtWriter;
  137. /// Base node.
  138. SourceLocation LPLoc; /// The location of the left paren
  139. SourceLocation RPLoc; /// The location of the right paren
  140. unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
  141. /// Construct full expression.
  142. OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
  143. SourceLocation R, ArrayRef<Expr *> Dims);
  144. /// Construct an empty expression.
  145. explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
  146. : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
  147. /// Sets the dimensions for the array shaping.
  148. void setDimensions(ArrayRef<Expr *> Dims);
  149. /// Sets the base expression for array shaping operation.
  150. void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
  151. /// Sets source ranges for the brackets in the array shaping operation.
  152. void setBracketsRanges(ArrayRef<SourceRange> BR);
  153. unsigned numTrailingObjects(OverloadToken<Expr *>) const {
  154. // Add an extra one for the base expression.
  155. return NumDims + 1;
  156. }
  157. unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
  158. return NumDims;
  159. }
  160. public:
  161. static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
  162. Expr *Op, SourceLocation L,
  163. SourceLocation R, ArrayRef<Expr *> Dims,
  164. ArrayRef<SourceRange> BracketRanges);
  165. static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
  166. unsigned NumDims);
  167. SourceLocation getLParenLoc() const { return LPLoc; }
  168. void setLParenLoc(SourceLocation L) { LPLoc = L; }
  169. SourceLocation getRParenLoc() const { return RPLoc; }
  170. void setRParenLoc(SourceLocation L) { RPLoc = L; }
  171. SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
  172. SourceLocation getEndLoc() const LLVM_READONLY {
  173. return getBase()->getEndLoc();
  174. }
  175. /// Fetches the dimensions for array shaping expression.
  176. ArrayRef<Expr *> getDimensions() const {
  177. return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
  178. }
  179. /// Fetches source ranges for the brackets os the array shaping expression.
  180. ArrayRef<SourceRange> getBracketsRanges() const {
  181. return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
  182. }
  183. /// Fetches base expression of array shaping expression.
  184. Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
  185. const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
  186. static bool classof(const Stmt *T) {
  187. return T->getStmtClass() == OMPArrayShapingExprClass;
  188. }
  189. // Iterators
  190. child_range children() {
  191. Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
  192. return child_range(Begin, Begin + NumDims + 1);
  193. }
  194. const_child_range children() const {
  195. Stmt *const *Begin =
  196. reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
  197. return const_child_range(Begin, Begin + NumDims + 1);
  198. }
  199. };
  200. /// Helper expressions and declaration for OMPIteratorExpr class for each
  201. /// iteration space.
  202. struct OMPIteratorHelperData {
  203. /// Internal normalized counter.
  204. VarDecl *CounterVD = nullptr;
  205. /// Normalized upper bound. Normalized loop iterates from 0 to Upper with
  206. /// step 1.
  207. Expr *Upper = nullptr;
  208. /// Update expression for the originally specified iteration variable,
  209. /// calculated as VD = Begin + CounterVD * Step;
  210. Expr *Update = nullptr;
  211. /// Updater for the internal counter: ++CounterVD;
  212. Expr *CounterUpdate = nullptr;
  213. };
  214. /// OpenMP 5.0 [2.1.6 Iterators]
  215. /// Iterators are identifiers that expand to multiple values in the clause on
  216. /// which they appear.
  217. /// The syntax of the iterator modifier is as follows:
  218. /// \code
  219. /// iterator(iterators-definition)
  220. /// \endcode
  221. /// where iterators-definition is one of the following:
  222. /// \code
  223. /// iterator-specifier [, iterators-definition ]
  224. /// \endcode
  225. /// where iterator-specifier is one of the following:
  226. /// \code
  227. /// [ iterator-type ] identifier = range-specification
  228. /// \endcode
  229. /// where identifier is a base language identifier.
  230. /// iterator-type is a type name.
  231. /// range-specification is of the form begin:end[:step], where begin and end are
  232. /// expressions for which their types can be converted to iterator-type and step
  233. /// is an integral expression.
  234. /// In an iterator-specifier, if the iterator-type is not specified then the
  235. /// type of that iterator is of int type.
  236. /// The iterator-type must be an integral or pointer type.
  237. /// The iterator-type must not be const qualified.
  238. class OMPIteratorExpr final
  239. : public Expr,
  240. private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
  241. SourceLocation, OMPIteratorHelperData> {
  242. public:
  243. /// Iterator range representation begin:end[:step].
  244. struct IteratorRange {
  245. Expr *Begin = nullptr;
  246. Expr *End = nullptr;
  247. Expr *Step = nullptr;
  248. };
  249. /// Iterator definition representation.
  250. struct IteratorDefinition {
  251. Decl *IteratorDecl = nullptr;
  252. IteratorRange Range;
  253. SourceLocation AssignmentLoc;
  254. SourceLocation ColonLoc, SecondColonLoc;
  255. };
  256. private:
  257. friend TrailingObjects;
  258. friend class ASTStmtReader;
  259. friend class ASTStmtWriter;
  260. /// Offset in the list of expressions for subelements of the ranges.
  261. enum class RangeExprOffset {
  262. Begin = 0,
  263. End = 1,
  264. Step = 2,
  265. Total = 3,
  266. };
  267. /// Offset in the list of locations for subelements of colon symbols
  268. /// locations.
  269. enum class RangeLocOffset {
  270. AssignLoc = 0,
  271. FirstColonLoc = 1,
  272. SecondColonLoc = 2,
  273. Total = 3,
  274. };
  275. /// Location of 'iterator' keyword.
  276. SourceLocation IteratorKwLoc;
  277. /// Location of '('.
  278. SourceLocation LPLoc;
  279. /// Location of ')'.
  280. SourceLocation RPLoc;
  281. /// Number of iterator definitions.
  282. unsigned NumIterators = 0;
  283. OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc,
  284. SourceLocation L, SourceLocation R,
  285. ArrayRef<IteratorDefinition> Data,
  286. ArrayRef<OMPIteratorHelperData> Helpers);
  287. /// Construct an empty expression.
  288. explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators)
  289. : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
  290. /// Sets basic declaration for the specified iterator definition.
  291. void setIteratorDeclaration(unsigned I, Decl *D);
  292. /// Sets the location of the assignment symbol for the specified iterator
  293. /// definition.
  294. void setAssignmentLoc(unsigned I, SourceLocation Loc);
  295. /// Sets begin, end and optional step expressions for specified iterator
  296. /// definition.
  297. void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc,
  298. Expr *End, SourceLocation SecondColonLoc, Expr *Step);
  299. /// Sets helpers for the specified iteration space.
  300. void setHelper(unsigned I, const OMPIteratorHelperData &D);
  301. unsigned numTrailingObjects(OverloadToken<Decl *>) const {
  302. return NumIterators;
  303. }
  304. unsigned numTrailingObjects(OverloadToken<Expr *>) const {
  305. return NumIterators * static_cast<int>(RangeExprOffset::Total);
  306. }
  307. unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
  308. return NumIterators * static_cast<int>(RangeLocOffset::Total);
  309. }
  310. public:
  311. static OMPIteratorExpr *Create(const ASTContext &Context, QualType T,
  312. SourceLocation IteratorKwLoc, SourceLocation L,
  313. SourceLocation R,
  314. ArrayRef<IteratorDefinition> Data,
  315. ArrayRef<OMPIteratorHelperData> Helpers);
  316. static OMPIteratorExpr *CreateEmpty(const ASTContext &Context,
  317. unsigned NumIterators);
  318. SourceLocation getLParenLoc() const { return LPLoc; }
  319. void setLParenLoc(SourceLocation L) { LPLoc = L; }
  320. SourceLocation getRParenLoc() const { return RPLoc; }
  321. void setRParenLoc(SourceLocation L) { RPLoc = L; }
  322. SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; }
  323. void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; }
  324. SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; }
  325. SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; }
  326. /// Gets the iterator declaration for the given iterator.
  327. Decl *getIteratorDecl(unsigned I);
  328. const Decl *getIteratorDecl(unsigned I) const {
  329. return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I);
  330. }
  331. /// Gets the iterator range for the given iterator.
  332. IteratorRange getIteratorRange(unsigned I);
  333. const IteratorRange getIteratorRange(unsigned I) const {
  334. return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I);
  335. }
  336. /// Gets the location of '=' for the given iterator definition.
  337. SourceLocation getAssignLoc(unsigned I) const;
  338. /// Gets the location of the first ':' in the range for the given iterator
  339. /// definition.
  340. SourceLocation getColonLoc(unsigned I) const;
  341. /// Gets the location of the second ':' (if any) in the range for the given
  342. /// iteratori definition.
  343. SourceLocation getSecondColonLoc(unsigned I) const;
  344. /// Returns number of iterator definitions.
  345. unsigned numOfIterators() const { return NumIterators; }
  346. /// Fetches helper data for the specified iteration space.
  347. OMPIteratorHelperData &getHelper(unsigned I);
  348. const OMPIteratorHelperData &getHelper(unsigned I) const;
  349. static bool classof(const Stmt *T) {
  350. return T->getStmtClass() == OMPIteratorExprClass;
  351. }
  352. // Iterators
  353. child_range children() {
  354. Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
  355. return child_range(
  356. Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
  357. }
  358. const_child_range children() const {
  359. Stmt *const *Begin =
  360. reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
  361. return const_child_range(
  362. Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
  363. }
  364. };
  365. } // end namespace clang
  366. #endif
  367. #ifdef __GNUC__
  368. #pragma GCC diagnostic pop
  369. #endif