Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

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