aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Evaluate/shape.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Evaluate/shape.cpp')
-rw-r--r--flang/lib/Evaluate/shape.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index c62d0cb..c7b2156 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -723,6 +723,58 @@ Shape GetUBOUNDs(const NamedEntity &base, bool invariantOnly) {
return GetUBOUNDs(nullptr, base, invariantOnly);
}
+MaybeExtentExpr GetLCOBOUND(
+ const Symbol &symbol0, int dimension, bool invariantOnly) {
+ const Symbol &symbol{ResolveAssociations(symbol0)};
+ if (const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
+ int corank{object->coshape().Rank()};
+ if (dimension < corank) {
+ const semantics::ShapeSpec &shapeSpec{object->coshape()[dimension]};
+ if (const auto &lcobound{shapeSpec.lbound().GetExplicit()}) {
+ if (!invariantOnly || IsScopeInvariantExpr(*lcobound)) {
+ return *lcobound;
+ }
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+MaybeExtentExpr GetUCOBOUND(
+ const Symbol &symbol0, int dimension, bool invariantOnly) {
+ const Symbol &symbol{ResolveAssociations(symbol0)};
+ if (const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
+ int corank{object->coshape().Rank()};
+ if (dimension < corank - 1) {
+ const semantics::ShapeSpec &shapeSpec{object->coshape()[dimension]};
+ if (const auto ucobound{shapeSpec.ubound().GetExplicit()}) {
+ if (!invariantOnly || IsScopeInvariantExpr(*ucobound)) {
+ return *ucobound;
+ }
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+Shape GetLCOBOUNDs(const Symbol &symbol, bool invariantOnly) {
+ Shape result;
+ int corank{symbol.Corank()};
+ for (int dim{0}; dim < corank; ++dim) {
+ result.emplace_back(GetLCOBOUND(symbol, dim, invariantOnly));
+ }
+ return result;
+}
+
+Shape GetUCOBOUNDs(const Symbol &symbol, bool invariantOnly) {
+ Shape result;
+ int corank{symbol.Corank()};
+ for (int dim{0}; dim < corank; ++dim) {
+ result.emplace_back(GetUCOBOUND(symbol, dim, invariantOnly));
+ }
+ return result;
+}
+
auto GetShapeHelper::operator()(const Symbol &symbol) const -> Result {
return common::visit(
common::visitors{
@@ -937,6 +989,10 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
if (!call.arguments().empty()) {
return (*this)(call.arguments()[0]);
}
+ } else if (intrinsic->name == "lcobound" || intrinsic->name == "ucobound") {
+ if (call.arguments().size() == 3 && !call.arguments().at(1).has_value()) {
+ return Shape(1, ExtentExpr{GetCorank(call.arguments().at(0))});
+ }
} else if (intrinsic->name == "matmul") {
if (call.arguments().size() == 2) {
if (auto ashape{(*this)(call.arguments()[0])}) {
@@ -1076,6 +1132,11 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result {
}
}
}
+ } else if (intrinsic->name == "this_image") {
+ if (call.arguments().size() == 2) {
+ // THIS_IMAGE(coarray, no DIM, [TEAM])
+ return Shape(1, ExtentExpr{GetCorank(call.arguments().at(0))});
+ }
} else if (intrinsic->name == "transpose") {
if (call.arguments().size() >= 1) {
if (auto shape{(*this)(call.arguments().at(0))}) {