diff options
Diffstat (limited to 'flang/lib/Evaluate/shape.cpp')
-rw-r--r-- | flang/lib/Evaluate/shape.cpp | 61 |
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))}) { |