blob: 5607d2d1dc588168a6eb749d8b9d7ccce5d54707 [file] [log] [blame]
Stephen Hines951613a2020-06-09 21:04:07 -07001//===--- 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