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/Expr.h" 17 18 namespace clang { 19 /// OpenMP 4.0 [2.4, Array Sections]. 20 /// To specify an array section in an OpenMP construct, array subscript 21 /// expressions are extended with the following syntax: 22 /// \code 23 /// [ lower-bound : length ] 24 /// [ lower-bound : ] 25 /// [ : length ] 26 /// [ : ] 27 /// \endcode 28 /// The array section must be a subset of the original array. 29 /// Array sections are allowed on multidimensional arrays. Base language array 30 /// subscript expressions can be used to specify length-one dimensions of 31 /// multidimensional array sections. 32 /// The lower-bound and length are integral type expressions. When evaluated 33 /// they represent a set of integer values as follows: 34 /// \code 35 /// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length - 36 /// 1 } 37 /// \endcode 38 /// The lower-bound and length must evaluate to non-negative integers. 39 /// When the size of the array dimension is not known, the length must be 40 /// specified explicitly. 41 /// When the length is absent, it defaults to the size of the array dimension 42 /// minus the lower-bound. 43 /// When the lower-bound is absent it defaults to 0. 44 class OMPArraySectionExpr : public Expr { 45 enum { BASE, LOWER_BOUND, LENGTH, END_EXPR }; 46 Stmt *SubExprs[END_EXPR]; 47 SourceLocation ColonLoc; 48 SourceLocation RBracketLoc; 49 50 public: 51 OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, 52 ExprValueKind VK, ExprObjectKind OK, 53 SourceLocation ColonLoc, SourceLocation RBracketLoc) 54 : Expr( 55 OMPArraySectionExprClass, Type, VK, OK, 56 Base->isTypeDependent() || 57 (LowerBound && LowerBound->isTypeDependent()) || 58 (Length && Length->isTypeDependent()), 59 Base->isValueDependent() || 60 (LowerBound && LowerBound->isValueDependent()) || 61 (Length && Length->isValueDependent()), 62 Base->isInstantiationDependent() || 63 (LowerBound && LowerBound->isInstantiationDependent()) || 64 (Length && Length->isInstantiationDependent()), 65 Base->containsUnexpandedParameterPack() || 66 (LowerBound && LowerBound->containsUnexpandedParameterPack()) || 67 (Length && Length->containsUnexpandedParameterPack())), 68 ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) { 69 SubExprs[BASE] = Base; 70 SubExprs[LOWER_BOUND] = LowerBound; 71 SubExprs[LENGTH] = Length; 72 } 73 74 /// Create an empty array section expression. 75 explicit OMPArraySectionExpr(EmptyShell Shell) 76 : Expr(OMPArraySectionExprClass, Shell) {} 77 78 /// An array section can be written only as Base[LowerBound:Length]. 79 80 /// Get base of the array section. 81 Expr *getBase() { return cast<Expr>(SubExprs[BASE]); } 82 const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); } 83 /// Set base of the array section. 84 void setBase(Expr *E) { SubExprs[BASE] = E; } 85 86 /// Return original type of the base expression for array section. 87 static QualType getBaseOriginalType(const Expr *Base); 88 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 97 /// Get length of array section. 98 Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); } 99 const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); } 100 /// Set length of the array section. 101 void setLength(Expr *E) { SubExprs[LENGTH] = E; } 102 103 SourceLocation getBeginLoc() const LLVM_READONLY { 104 return getBase()->getBeginLoc(); 105 } 106 SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } 107 108 SourceLocation getColonLoc() const { return ColonLoc; } 109 void setColonLoc(SourceLocation L) { ColonLoc = L; } 110 111 SourceLocation getRBracketLoc() const { return RBracketLoc; } 112 void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } 113 114 SourceLocation getExprLoc() const LLVM_READONLY { 115 return getBase()->getExprLoc(); 116 } 117 118 static bool classof(const Stmt *T) { 119 return T->getStmtClass() == OMPArraySectionExprClass; 120 } 121 122 child_range children() { 123 return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); 124 } 125 126 const_child_range children() const { 127 return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); 128 } 129 }; 130 } // end namespace clang 131 132 #endif 133