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
18namespace 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.
44class OMPArraySectionExpr : public Expr {
45  enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
46  Stmt *SubExprs[END_EXPR];
47  SourceLocation ColonLoc;
48  SourceLocation RBracketLoc;
49
50public:
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