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:
OMPArraySectionExpr(Expr * Base,Expr * LowerBound,Expr * Length,QualType Type,ExprValueKind VK,ExprObjectKind OK,SourceLocation ColonLoc,SourceLocation RBracketLoc)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.
OMPArraySectionExpr(EmptyShell Shell)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.
getBase()81   Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
getBase()82   const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
83   /// Set base of the array section.
setBase(Expr * E)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.
getLowerBound()90   Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
getLowerBound()91   const Expr *getLowerBound() const {
92     return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
93   }
94   /// Set lower bound of the array section.
setLowerBound(Expr * E)95   void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
96 
97   /// Get length of array section.
getLength()98   Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
getLength()99   const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
100   /// Set length of the array section.
setLength(Expr * E)101   void setLength(Expr *E) { SubExprs[LENGTH] = E; }
102 
getBeginLoc()103   SourceLocation getBeginLoc() const LLVM_READONLY {
104     return getBase()->getBeginLoc();
105   }
getEndLoc()106   SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
107 
getColonLoc()108   SourceLocation getColonLoc() const { return ColonLoc; }
setColonLoc(SourceLocation L)109   void setColonLoc(SourceLocation L) { ColonLoc = L; }
110 
getRBracketLoc()111   SourceLocation getRBracketLoc() const { return RBracketLoc; }
setRBracketLoc(SourceLocation L)112   void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
113 
getExprLoc()114   SourceLocation getExprLoc() const LLVM_READONLY {
115     return getBase()->getExprLoc();
116   }
117 
classof(const Stmt * T)118   static bool classof(const Stmt *T) {
119     return T->getStmtClass() == OMPArraySectionExprClass;
120   }
121 
children()122   child_range children() {
123     return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
124   }
125 
children()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