1//===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Expr interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_EXPROPENMP_H
15#define LLVM_CLANG_AST_EXPROPENMP_H
16
17#include "clang/AST/Expr.h"
18
19namespace clang {
20/// \brief OpenMP 4.0 [2.4, 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 ]
25/// [ lower-bound : ]
26/// [ : length ]
27/// [ : ]
28/// \endcode
29/// The array section must be a subset of the original array.
30/// Array sections are allowed on multidimensional arrays. Base language array
31/// subscript expressions can be used to specify length-one dimensions of
32/// multidimensional array sections.
33/// The lower-bound and length are integral type expressions. When evaluated
34/// they represent a set of integer values as follows:
35/// \code
36/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
37/// 1 }
38/// \endcode
39/// The lower-bound and length must evaluate to non-negative integers.
40/// When the size of the array dimension is not known, the length must be
41/// specified explicitly.
42/// When the length is absent, it defaults to the size of the array dimension
43/// minus the lower-bound.
44/// When the lower-bound is absent it defaults to 0.
45class OMPArraySectionExpr : public Expr {
46  enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
47  Stmt *SubExprs[END_EXPR];
48  SourceLocation ColonLoc;
49  SourceLocation RBracketLoc;
50
51public:
52  OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
53                      ExprValueKind VK, ExprObjectKind OK,
54                      SourceLocation ColonLoc, SourceLocation RBracketLoc)
55      : Expr(
56            OMPArraySectionExprClass, Type, VK, OK,
57            Base->isTypeDependent() ||
58                (LowerBound && LowerBound->isTypeDependent()) ||
59                (Length && Length->isTypeDependent()),
60            Base->isValueDependent() ||
61                (LowerBound && LowerBound->isValueDependent()) ||
62                (Length && Length->isValueDependent()),
63            Base->isInstantiationDependent() ||
64                (LowerBound && LowerBound->isInstantiationDependent()) ||
65                (Length && Length->isInstantiationDependent()),
66            Base->containsUnexpandedParameterPack() ||
67                (LowerBound && LowerBound->containsUnexpandedParameterPack()) ||
68                (Length && Length->containsUnexpandedParameterPack())),
69        ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) {
70    SubExprs[BASE] = Base;
71    SubExprs[LOWER_BOUND] = LowerBound;
72    SubExprs[LENGTH] = Length;
73  }
74
75  /// \brief Create an empty array section expression.
76  explicit OMPArraySectionExpr(EmptyShell Shell)
77      : Expr(OMPArraySectionExprClass, Shell) {}
78
79  /// An array section can be written only as Base[LowerBound:Length].
80
81  /// \brief Get base of the array section.
82  Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
83  const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
84  /// \brief Set base of the array section.
85  void setBase(Expr *E) { SubExprs[BASE] = E; }
86
87  /// \brief Return original type of the base expression for array section.
88  static QualType getBaseOriginalType(const Expr *Base);
89
90  /// \brief Get lower bound of array section.
91  Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
92  const Expr *getLowerBound() const {
93    return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
94  }
95  /// \brief Set lower bound of the array section.
96  void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
97
98  /// \brief Get length of array section.
99  Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
100  const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
101  /// \brief Set length of the array section.
102  void setLength(Expr *E) { SubExprs[LENGTH] = E; }
103
104  SourceLocation getLocStart() const LLVM_READONLY {
105    return getBase()->getLocStart();
106  }
107  SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
108
109  SourceLocation getColonLoc() const { return ColonLoc; }
110  void setColonLoc(SourceLocation L) { ColonLoc = L; }
111
112  SourceLocation getRBracketLoc() const { return RBracketLoc; }
113  void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
114
115  SourceLocation getExprLoc() const LLVM_READONLY {
116    return getBase()->getExprLoc();
117  }
118
119  static bool classof(const Stmt *T) {
120    return T->getStmtClass() == OMPArraySectionExprClass;
121  }
122
123  child_range children() {
124    return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
125  }
126};
127} // end namespace clang
128
129#endif
130