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(
const A &,
bool invariantOnly =
true);
86ExtentExpr GetRawLowerBound(
87 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
88ExtentExpr GetRawLowerBound(FoldingContext &,
const NamedEntity &,
89 int dimension,
bool invariantOnly =
true);
90MaybeExtentExpr GetLBOUND(
91 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
92MaybeExtentExpr GetLBOUND(FoldingContext &,
const NamedEntity &,
int dimension,
93 bool invariantOnly =
true);
94MaybeExtentExpr GetRawUpperBound(
95 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
96MaybeExtentExpr GetRawUpperBound(FoldingContext &,
const NamedEntity &,
97 int dimension,
bool invariantOnly =
true);
98MaybeExtentExpr GetUBOUND(
99 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
100MaybeExtentExpr GetUBOUND(FoldingContext &,
const NamedEntity &,
int dimension,
101 bool invariantOnly =
true);
102MaybeExtentExpr ComputeUpperBound(ExtentExpr &&lower, MaybeExtentExpr &&extent);
103MaybeExtentExpr ComputeUpperBound(
104 FoldingContext &, ExtentExpr &&lower, MaybeExtentExpr &&extent);
105Shape GetRawLowerBounds(
const NamedEntity &,
bool invariantOnly =
true);
106Shape GetRawLowerBounds(
107 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
108Shape GetLBOUNDs(
const NamedEntity &,
bool invariantOnly =
true);
110 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
111Shape GetUBOUNDs(
const NamedEntity &,
bool invariantOnly =
true);
113 FoldingContext &,
const NamedEntity &,
bool invariantOnly =
true);
114MaybeExtentExpr GetExtent(
115 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
116MaybeExtentExpr GetExtent(FoldingContext &,
const NamedEntity &,
int dimension,
117 bool invariantOnly =
true);
118MaybeExtentExpr GetExtent(
const Subscript &,
const NamedEntity &,
int dimension,
119 bool invariantOnly =
true);
120MaybeExtentExpr GetExtent(FoldingContext &,
const Subscript &,
121 const NamedEntity &,
int dimension,
bool invariantOnly =
true);
124MaybeExtentExpr GetLCOBOUND(
125 const Symbol &,
int dimension,
bool invariantOnly =
true);
126MaybeExtentExpr GetUCOBOUND(
127 const Symbol &,
int dimension,
bool invariantOnly =
true);
128Shape GetLCOBOUNDs(
const Symbol &,
bool invariantOnly =
true);
129Shape GetUCOBOUNDs(
const Symbol &,
bool invariantOnly =
true);
132ExtentExpr CountTrips(
133 ExtentExpr &&lower, ExtentExpr &&upper, ExtentExpr &&stride);
134ExtentExpr CountTrips(
135 const ExtentExpr &lower,
const ExtentExpr &upper,
const ExtentExpr &stride);
136MaybeExtentExpr CountTrips(
137 MaybeExtentExpr &&lower, MaybeExtentExpr &&upper, MaybeExtentExpr &&stride);
140MaybeExtentExpr GetSize(Shape &&);
141ConstantSubscript GetSize(
const ConstantSubscripts &);
142inline MaybeExtentExpr GetSize(
const std::optional<Shape> &maybeShape) {
144 return GetSize(Shape(*maybeShape));
150bool ContainsAnyImpliedDoIndex(
const ExtentExpr &);
153 :
public AnyTraverse<GetShapeHelper, std::optional<Shape>> {
155 using Result = std::optional<Shape>;
157 using Base::operator();
159 :
Base{*
this}, context_{context}, invariantOnly_{invariantOnly} {}
161 Result operator()(
const ImpliedDoIndex &)
const {
return ScalarShape(); }
164 Result operator()(
const BOZLiteralConstant &)
const {
return ScalarShape(); }
165 Result operator()(
const StaticDataObject::Pointer &)
const {
166 return ScalarShape();
169 return ScalarShape();
172 template <
typename T> Result operator()(
const Constant<T> &c)
const {
173 return ConstantShape(c.SHAPE());
176 Result operator()(
const Symbol &)
const;
177 Result operator()(
const Component &)
const;
178 Result operator()(
const ArrayRef &)
const;
180 Result operator()(
const Substring &)
const;
183 template <
typename T>
185 return Shape{GetArrayConstructorExtent(aconst)};
187 template <
typename D,
typename R,
typename LO,
typename RO>
189 if (
int rr{operation.right().Rank()}; rr > 0) {
190 if (
int lr{operation.left().Rank()}; lr == 0 || lr == rr) {
191 return (*
this)(operation.right());
196 return (*
this)(operation.left());
201 static Result ScalarShape() {
return Shape{}; }
206 template <
typename T>
207 MaybeExtentExpr GetArrayConstructorValueExtent(
209 return common::visit(
211 [&](
const Expr<T> &x) -> MaybeExtentExpr {
212 if (
auto xShape{(*this)(x)}) {
214 return GetSize(std::move(*xShape));
222 if (!ContainsAnyImpliedDoIndex(ido.lower()) &&
223 !ContainsAnyImpliedDoIndex(ido.upper()) &&
224 !ContainsAnyImpliedDoIndex(ido.stride())) {
225 if (
auto nValues{GetArrayConstructorExtent(ido.values())}) {
226 if (!ContainsAnyImpliedDoIndex(*nValues)) {
227 return std::move(*nValues) *
228 CountTrips(ido.lower(), ido.upper(), ido.stride());
238 template <
typename T>
239 MaybeExtentExpr GetArrayConstructorExtent(
242 for (
const auto &value : values) {
243 if (MaybeExtentExpr n{GetArrayConstructorValueExtent(value)}) {
244 AccumulateExtent(result, std::move(*n));
256 mutable bool useResultSymbolShape_{
true};
259 bool invariantOnly_{
true};
263std::optional<Shape> GetShape(
266 return Fold(context, std::move(shape));
273std::optional<Shape> GetShape(
const A &x,
bool invariantOnly) {
274 return GetShapeHelper{
nullptr, invariantOnly}(x);
278std::optional<Shape> GetShape(
279 FoldingContext *context,
const A &x,
bool invariantOnly =
true) {
280 return GetShapeHelper{context, invariantOnly}(x);
284std::optional<Constant<ExtentType>> GetConstantShape(
285 FoldingContext &context,
const A &x) {
286 if (
auto shape{GetShape(context, x,
true)}) {
287 return AsConstantShape(context, *shape);
295std::optional<ConstantSubscripts> GetConstantExtents(
296 FoldingContext &context,
const A &x) {
297 if (
auto shape{GetShape(context, x,
true)}) {
298 if (
auto extents{AsConstantExtents(context, *shape)}) {
299 if (!HasNegativeExtent(*extents)) {
312std::optional<Shape> GetContextFreeShape(FoldingContext &context,
const A &x) {
313 return GetShapeHelper{&context,
true}(x);
328 LeftScalarExpandable = 1,
329 RightScalarExpandable = 2,
330 LeftIsDeferredShape = 4,
331 RightIsDeferredShape = 8,
332 EitherScalarExpandable = LeftScalarExpandable | RightScalarExpandable,
333 BothDeferredShape = LeftIsDeferredShape | RightIsDeferredShape,
334 RightIsExpandableDeferred = RightScalarExpandable | RightIsDeferredShape,
338 const Shape &left,
const Shape &right,
339 CheckConformanceFlags::Flags flags = CheckConformanceFlags::None,
340 const char *leftIs =
"left operand",
const char *rightIs =
"right operand");
346bool IncrementSubscripts(
347 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