12#ifndef FORTRAN_EVALUATE_SHAPE_H_
13#define FORTRAN_EVALUATE_SHAPE_H_
15#include "expression.h"
18#include "flang/Common/indirection.h"
19#include "flang/Evaluate/type.h"
24class ContextualMessages;
31using ExtentType = SubscriptInteger;
32using ExtentExpr = Expr<ExtentType>;
33using MaybeExtentExpr = std::optional<ExtentExpr>;
34using Shape = std::vector<MaybeExtentExpr>;
36bool IsImpliedShape(
const Symbol &);
37bool IsExplicitShape(
const Symbol &);
40std::optional<ExtentExpr> AsExtentArrayExpr(
const Shape &);
42std::optional<Constant<ExtentType>> AsConstantShape(
43 FoldingContext &,
const Shape &);
44Constant<ExtentType> AsConstantShape(
const ConstantSubscripts &);
48ConstantSubscripts AsConstantExtents(
const Constant<ExtentType> &);
49std::optional<ConstantSubscripts> AsConstantExtents(
50 FoldingContext &,
const Shape &);
51inline std::optional<ConstantSubscripts> AsConstantExtents(
52 FoldingContext &foldingContext,
const std::optional<Shape> &maybeShape) {
54 return AsConstantExtents(foldingContext, *maybeShape);
59Shape AsShape(
const ConstantSubscripts &);
60std::optional<Shape> AsShape(
const std::optional<ConstantSubscripts> &);
62inline int GetRank(
const Shape &s) {
return static_cast<int>(s.size()); }
64Shape Fold(FoldingContext &, Shape &&);
65std::optional<Shape> Fold(FoldingContext &, std::optional<Shape> &&);
71std::optional<Shape> GetShape(
72 FoldingContext &,
const A &,
bool invariantOnly =
true);
74std::optional<Shape> GetShape(
75 FoldingContext *,
const A &,
bool invariantOnly =
true);
77std::optional<Shape> GetShape(
const A &,
bool invariantOnly =
true);
89ExtentExpr GetRawLowerBound(
90 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
91ExtentExpr GetRawLowerBound(FoldingContext &,
const NamedEntity &,
92 int dimension,
bool invariantOnly =
true);
93MaybeExtentExpr GetLBOUND(
94 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
95MaybeExtentExpr GetLBOUND(FoldingContext &,
const NamedEntity &,
int dimension,
96 bool invariantOnly =
true);
97MaybeExtentExpr GetRawUpperBound(
98 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
99MaybeExtentExpr GetRawUpperBound(FoldingContext &,
const NamedEntity &,
100 int dimension,
bool invariantOnly =
true);
101MaybeExtentExpr GetUBOUND(
102 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
103MaybeExtentExpr GetUBOUND(FoldingContext &,
const NamedEntity &,
int dimension,
104 bool invariantOnly =
true);
105MaybeExtentExpr ComputeUpperBound(ExtentExpr &&lower, MaybeExtentExpr &&extent);
106MaybeExtentExpr ComputeUpperBound(
107 FoldingContext &, ExtentExpr &&lower, MaybeExtentExpr &&extent);
108Shape GetRawLowerBounds(
const NamedEntity &,
bool invariantOnly =
true);
109Shape GetRawLowerBounds(
110 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
111Shape GetLBOUNDs(
const NamedEntity &,
bool invariantOnly =
true);
113 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
114Shape GetUBOUNDs(
const NamedEntity &,
bool invariantOnly =
true);
116 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
117MaybeExtentExpr GetExtent(
118 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
119MaybeExtentExpr GetExtent(FoldingContext &,
const NamedEntity &,
int dimension,
120 bool invariantOnly =
true);
121MaybeExtentExpr GetExtent(
const Subscript &,
const NamedEntity &,
int dimension,
122 bool invariantOnly =
true);
123MaybeExtentExpr GetExtent(FoldingContext &,
const Subscript &,
124 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
127MaybeExtentExpr GetLCOBOUND(
128 const Symbol &,
int dimension,
bool invariantOnly =
true);
129MaybeExtentExpr GetUCOBOUND(
130 const Symbol &,
int dimension,
bool invariantOnly =
true);
131Shape GetLCOBOUNDs(
const Symbol &,
bool invariantOnly =
true);
132Shape GetUCOBOUNDs(
const Symbol &,
bool invariantOnly =
true);
135ExtentExpr CountTrips(
136 ExtentExpr &&lower, ExtentExpr &&upper, ExtentExpr &&stride);
137ExtentExpr CountTrips(
138 const ExtentExpr &lower,
const ExtentExpr &upper,
const ExtentExpr &stride);
139MaybeExtentExpr CountTrips(
140 MaybeExtentExpr &&lower, MaybeExtentExpr &&upper, MaybeExtentExpr &&stride);
143MaybeExtentExpr GetSize(Shape &&);
144ConstantSubscript GetSize(
const ConstantSubscripts &);
145inline MaybeExtentExpr GetSize(
const std::optional<Shape> &maybeShape) {
147 return GetSize(Shape(*maybeShape));
153bool ContainsAnyImpliedDoIndex(
const ExtentExpr &);
158 :
public AnyTraverse<GetShapeHelper, std::optional<Shape>> {
160 using Result = std::optional<Shape>;
162 using Base::operator();
164 :
Base{*
this}, context_{context}, invariantOnly_{invariantOnly} {}
166 Result operator()(
const ImpliedDoIndex &)
const {
return ScalarShape(); }
169 Result operator()(
const BOZLiteralConstant &)
const {
return ScalarShape(); }
170 Result operator()(
const StaticDataObject::Pointer &)
const {
171 return ScalarShape();
174 return ScalarShape();
177 template <
typename T> Result operator()(
const Constant<T> &c)
const {
178 return ConstantShape(c.SHAPE());
181 Result operator()(
const Symbol &)
const;
182 Result operator()(
const Component &)
const;
183 Result operator()(
const ArrayRef &)
const;
185 Result operator()(
const Substring &)
const;
188 template <
typename T>
190 return Shape{GetArrayConstructorExtent(aconst)};
192 template <
typename D,
typename R,
typename LO,
typename RO>
194 if (
int rr{operation.right().Rank()}; rr > 0) {
195 if (
int lr{operation.left().Rank()}; lr == 0 || lr == rr) {
196 return (*
this)(operation.right());
201 return (*
this)(operation.left());
206 static Result ScalarShape() {
return Shape{}; }
211 template <
typename T>
212 MaybeExtentExpr GetArrayConstructorValueExtent(
214 return common::visit(
216 [&](
const Expr<T> &x) -> MaybeExtentExpr {
217 if (
auto xShape{(*this)(x)}) {
219 return GetSize(std::move(*xShape));
227 if (!ContainsAnyImpliedDoIndex(ido.lower()) &&
228 !ContainsAnyImpliedDoIndex(ido.upper()) &&
229 !ContainsAnyImpliedDoIndex(ido.stride())) {
230 if (
auto nValues{GetArrayConstructorExtent(ido.values())}) {
231 if (!ContainsAnyImpliedDoIndex(*nValues)) {
232 return std::move(*nValues) *
233 CountTrips(ido.lower(), ido.upper(), ido.stride());
243 template <
typename T>
244 MaybeExtentExpr GetArrayConstructorExtent(
247 for (
const auto &value : values) {
248 if (MaybeExtentExpr n{GetArrayConstructorValueExtent(value)}) {
249 AccumulateExtent(result, std::move(*n));
261 mutable bool useResultSymbolShape_{
true};
264 bool invariantOnly_{
true};
268std::optional<Shape> GetShape(
272 return Fold(*context, std::move(shape));
282std::optional<Shape> GetShape(
283 FoldingContext &context,
const A &x,
bool invariantOnly) {
284 return GetShape(&context, x, invariantOnly);
288std::optional<Shape> GetShape(
const A &x,
bool invariantOnly) {
289 return GetShape(
nullptr, x, invariantOnly);
293std::optional<Constant<ExtentType>> GetConstantShape(
294 FoldingContext &context,
const A &x) {
295 if (
auto shape{GetShape(context, x,
true)}) {
296 return AsConstantShape(context, *shape);
304std::optional<ConstantSubscripts> GetConstantExtents(
305 FoldingContext &context,
const A &x) {
306 if (
auto shape{GetShape(context, x,
true)}) {
307 if (
auto extents{AsConstantExtents(context, *shape)}) {
308 if (!HasNegativeExtent(*extents)) {
321std::optional<Shape> GetContextFreeShape(FoldingContext &context,
const A &x) {
322 return GetShapeHelper{&context,
true}(x);
337 LeftScalarExpandable = 1,
338 RightScalarExpandable = 2,
339 LeftIsDeferredShape = 4,
340 RightIsDeferredShape = 8,
341 EitherScalarExpandable = LeftScalarExpandable | RightScalarExpandable,
342 BothDeferredShape = LeftIsDeferredShape | RightIsDeferredShape,
343 RightIsExpandableDeferred = RightScalarExpandable | RightIsDeferredShape,
347 const Shape &left,
const Shape &right,
348 CheckConformanceFlags::Flags flags = CheckConformanceFlags::None,
349 const char *leftIs =
"left operand",
const char *rightIs =
"right operand");
355bool IncrementSubscripts(
356 ConstantSubscripts &,
const ConstantSubscripts &extents);
Definition: traverse.h:305
Definition: expression.h:438
Definition: expression.h:466
Definition: variable.h:208
Definition: variable.h:255
Definition: variable.h:74
Definition: constant.h:141
Definition: variable.h:425
Definition: expression.h:404
Definition: variable.h:104
Definition: expression.h:114
Definition: expression.h:740
Definition: variable.h:316
Definition: variable.h:139
Definition: message.h:363
Definition: check-expression.h:19
Definition: expression.h:432
Definition: expression.h:396